<![CDATA[Magento开发教程及电子商务最新动态]]> https://www.360magento.com/blog/ Thu, 19 Feb 2026 10:46:32 +0000 Zend_Feed http://blogs.law.harvard.edu/tech/rss <![CDATA[Magento如何将附件添加到邮件中]]> https://www.360magento.com/blog/add-attachments-to-magento-email/ 在 Magento 中,增强沟通策略可以显著提高客户满意度和参与度。其中一种有效的方法就是在电子邮件中添加附件,为客户提供详细的信息,并改善整体用户体验。 

在这篇博文中,我们将指导您完成创建 Magento 模块的过程,以将发票自动附加到您的电子邮件中,从而增强整体用户体验。

为什么向Magento 电子邮件添加附件是一项有价值的增强功能

事实证明,将文件附加到 Magento 电子邮件对企业和客户都有利。

与企业

提高效率并节省时间

通过预先自动准备发票附件,企业可以节省时间和精力。发件人可以轻松点击“发送”,简化沟通过程。

专业的品牌形象

将精心设计的附件包含在内有助于公司树立专业形象。这反映了对组织有序和详细沟通的承诺,提升了业务的整体感知。

与客户

全面的订单详情

附件提供给客户详细的订单信息,例如发票、收据和运输详情,直接在电子邮件中。这消除了客户需要在外部平台导航的必要,确保他们全面了解自己的购买。

简化沟通

附件采用了易于理解的格式,减少了客户阅读冗长电子邮件的必要性。重要信息被清晰、简洁地呈现,从而提升了整体用户体验。

在Magento电子邮件中添加发票附件的步骤说明

1. 创建模块文件

首先,您需要使用以下文件设置模块的基本结构:

文件 di.xml

<?xml version="1.0"?>
 
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <preference for="Magento\Framework\Mail\Template\TransportBuilder"
           	type="Alwayly\SendPdf\Mail\Template\TransportBuilder"/>
   <type name="Magento\Sales\Model\Order\Email\SenderBuilder">
   	<plugin name="add.attachment.email" type="Alwayly\SendPdf\Plugin\SenderBuilder"/>
   </type>
</config>

文件 module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
   <module name="Alwayly_SendPdf" />
</config>

文件 registration.php

<?php
/*
* @author  Alwayly Solutions <info@Alwayly.com>
* @copyright Copyright (c) 2023 Alwayly Solutions <https://www.alwayly.com>. All rights reserved.
* @license  Open Software License (“OSL”) v. 3.0
*/
 
use Magento\Framework\Component\ComponentRegistrar;
 
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Alwayly_SendPdf', __DIR__);

2. 重写TransportBuilder 

然后,我们需要覆盖Magento 中Alwayly\SendPdf\Mail\Template目录中的TransportBuilder文件以包含附件功能。

<?php
 
declare (strict_types=1);
 
namespace Alwayly\SendPdf\Mail\Template;
 
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Mail\AddressConverter;
use Magento\Framework\Mail\EmailMessageInterfaceFactory;
use Magento\Framework\Mail\MessageInterface;
use Magento\Framework\Mail\MessageInterfaceFactory;
use Magento\Framework\Mail\MimeMessageInterfaceFactory;
use Magento\Framework\Mail\MimePartInterfaceFactory;
use Magento\Framework\Mail\Template\FactoryInterface;
use Magento\Framework\Mail\Template\SenderResolverInterface;
use Magento\Framework\Mail\TransportInterfaceFactory;
use Magento\Framework\ObjectManagerInterface;
use Laminas\Mime\Mime;
use Laminas\Mime\Message;
use Laminas\Mime\PartFactory;
 
/**
* Class TransportBuilder
* @package Alwayly\SendPdf\Mail\Template
*/
class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder
{
   /**
	* @var Message
	*/
   protected $messageMime;
 
   /**
	* @var
	*/
   protected $message;
 
   /**
	* @var array
	*/
   protected $attachments = [];
 
   /**
	* @var PartFactory|mixed
	*/
   protected $partFactory;
 
   /**
	* @param Message $messageMime
	* @param PartFactory $partFactory
	* @param FactoryInterface $templateFactory
	* @param MessageInterface $message
	* @param SenderResolverInterface $senderResolver
	* @param ObjectManagerInterface $objectManager
	* @param TransportInterfaceFactory $mailTransportFactory
	* @param MessageInterfaceFactory|null $messageFactory
	* @param EmailMessageInterfaceFactory|null $emailMessageInterfaceFactory
	* @param MimeMessageInterfaceFactory|null $mimeMessageInterfaceFactory
	* @param MimePartInterfaceFactory|null $mimePartInterfaceFactory
	* @param AddressConverter|null $addressConverter
	*/
   public function __construct(
   	Message $messageMime,
   	PartFactory $partFactory,
   	FactoryInterface $templateFactory,
   	MessageInterface $message,
   	SenderResolverInterface $senderResolver,
   	ObjectManagerInterface $objectManager,
   	TransportInterfaceFactory $mailTransportFactory,
   	MessageInterfaceFactory $messageFactory = null,
   	EmailMessageInterfaceFactory $emailMessageInterfaceFactory = null,
   	MimeMessageInterfaceFactory $mimeMessageInterfaceFactory = null,
   	MimePartInterfaceFactory $mimePartInterfaceFactory = null,
   	AddressConverter $addressConverter = null
   ) {
   	$this->templateFactory = $templateFactory;
   	$this->partFactory = $partFactory;
   	$this->messageMime = $messageMime;
   	parent::__construct(
       	$templateFactory,
       	$message,
       	$senderResolver,
       	$objectManager,
       	$mailTransportFactory,
       	$messageFactory,
       	$emailMessageInterfaceFactory,
       	$mimeMessageInterfaceFactory,
       	$mimePartInterfaceFactory,
       	$addressConverter
   	);
   }
 
   /**
	* @return $this|TransportBuilder
	* @throws LocalizedException
	*/
 protected function prepareMessage()
   {
   	$result = parent::prepareMessage();
   	if (!empty($this->attachments)) {
       	foreach ($this->attachments as $attachment) {
           	$body = $this->message->getBody();
           	if (!$body) {
               	$body = $this->messageMime;
           	}
           	$body->addPart($attachment);
           	$this->message->setBody($body);
       	}
       	$this->attachments = [];
   	}
   	return $result;
   }
 
   /**
	* @param $content
	* @param $fileName
	* @param $fileType
	* @return $this
	*/
   public function addAttachment($content, $fileName, $fileType)
   {
   	$attachmentPart = $this->partFactory->create();
   	$attachmentPart->setContent($content)
       	->setType($fileType)
       	->setFileName($fileName)
       	->setDisposition(Mime::DISPOSITION_ATTACHMENT)
       	->setEncoding(Mime::ENCODING_BASE64);
   	$this->attachments[] = $attachmentPart;
 
   	return $this;
   }
}

3. SenderBuilder插件

<?php
 
namespace Alwayly\SendPdf\Plugin;
 
use Laminas\Validator\Date;
use Alwayly\SendPdf\Mail\Template\TransportBuilder;
use Magento\Sales\Model\Order\Email\Container\Template;
use Magento\Sales\Model\Order\Pdf\Invoice;
use Magento\Framework\Stdlib\DateTime\DateTime;
 
class SenderBuilder
{
   private TransportBuilder $transportBuilder;
 
   private Template $templateContainer;
 
   private Invoice $renderInvoice;
 
   private DateTime $dateTime;
 
   public function __construct(
   	DateTime $dateTime,
   	Invoice $renderInvoice,
   	Template $templateContainer,
   	TransportBuilder $transportBuilder
   ) {
   	$this->transportBuilder = $transportBuilder;
   	$this->templateContainer = $templateContainer;
   	$this->renderInvoice = $renderInvoice;
   	$this->dateTime = $dateTime;
   }
 
   public function beforeSend(\Magento\Sales\Model\Order\Email\SenderBuilder $subject)
   {
   	$dataInvoice = $this->_getDataTemplate();
   	try {
       	if(!empty($dataInvoice)){
           	$pdfContent = $this->renderInvoice->getPdf($dataInvoice)->render();
           	$date = $this->dateTime->date('Y-m-d_H-i-s');
           	$this->transportBuilder->addAttachment($pdfContent, 'invoice' . $date . '.pdf', 'application/pdf');
       	}
   	} catch (\Exception $e) {
       	return;
   	}
   }
 
   private function _getDataTemplate()
   {
   	$data = $this->templateContainer->getTemplateVars();
   	if (array_key_exists('invoice_id', $data)) {
       	return [$data['invoice']];
   	}
   	if (isset($data['order']) && $data['order']->hasInvoices()) {
       	return $data['order']->getInvoiceCollection()->getItems();
   	}
   	return [$data['invoice']] ?? '';
   }

结果

当发出发票或订单的电子邮件时,会自动地在邮件中添加发票附件。

Magento 邮件附件

总结

总之,按照这些步骤,您可以轻松地将发票附件添加到Magento的电子邮件中。这样做可以增强您的沟通策略,为客户提供详细信息,从而促进积极的购物体验。

根据您的具体需求对该模块进行定制,从而在竞争激烈的电子商务市场中提高客户参与度。如果需要,欢迎联系我们,我们为您提供更多的Magento平台定制服务。

]]>
Wed, 27 Mar 2024 05:29:11 +0000
<![CDATA[如何在 Magento 2 中显示/删除 CMS 页面的面包屑导航]]> https://www.360magento.com/blog/how-to-show-breadcrumbs-to-cms-pages-magento/ 实践中常见的 3 种面包屑类型

面包屑主要分为三种类型。每个都有其自己的目的和不同的用途。以下是您在网站上有效实施面包屑的 3 种方法。

总之,强烈建议您在 Magento 商店中添加面包屑,尽管它不是网站的强制组件。

基于层次结构的面包屑

这被认为是使用最广泛和最常见的面包屑类型。本质上,基于层次结构的面包屑告诉网络访问者他们在网站结构中的位置。每个文本链接所指向的页面比其右侧的页面高一级。

我们以亚马逊为例。当打开亚马逊上的任何产品页面时,您可以轻松地在页面的左上角看到类似这样的面包屑痕迹。

例如:电子产品 > 计算机及配件 > 计算机配件及外围设备。

显然,这种类型的面包屑可以帮助用户轻松查看他们在网站架构中的位置。当您可以与面包屑路径的每个部分进行交互时,导航到较低或较高级别的页面也变得更加方便。

基于历史的面包屑

与基于层次结构的面包屑不同,基于历史(或基于路径)的面包屑具有与浏览器后退按钮相同的功能。它允许用户快速返回到他们访问过的先前页面,并且所有选择都完好无损。

当访问者在类别页面上应用多个过滤器后只想快速跳回到上一页时,这种类型的面包屑链接非常有用。它关注的是实际的点击路径而不是位置。

基于属性的面包屑

除了第一种面包屑类型之外,基于属性的面包屑是电子商务网站上使用最广泛的两种面包屑类型。

顾名思义,这种面包屑类型包含产品属性,这些属性向客户显示他们点击了哪些属性。

基于属性的面包屑与基于层次结构的面包屑最显着的区别在于,它不仅列出您的路径,还表示您在产品上选择的过滤器(价格、质量、颜色等)。您还可以直接在面包屑路径上取消选择产品过滤器。

为什么面包屑对电子商务商店很重要?

对于电子商务企业来说,面包屑在帮助用户有效地浏览整个网站和页面之间发挥着至关重要的作用。

然而,面包屑不仅仅局限于改善用户的浏览体验,它在很多方面都更有益。

提升用户体验

不用说,面包屑使网络访问者可以更轻松地系统地浏览整个在线商店。当顾客在您的商店里闲逛时迷路时,您只需要面包屑路径即可为他们指明出路。

通过正确实施面包屑类型,您可以帮助用户眨眼间移动到他们想要的页面。

尽管面包屑只是一种常见的界面元素,但它有助于减少摩擦并为客户带来便利。

降低跳出率

面包屑本身的另一个好处是能够降低跳出率。如前所述,面包屑可以作为一种方便的指南:

  • 向用户准确显示他们在您网站上的位置
  • 只需单击一下即可根据客户的偏好向后或向前导航

换句话说,您为网络访问者提供了一种使用面包屑导航轻松浏览您的网站的便捷方式。

因此,面包屑的应用提高了可用性、价值、网站的可信度以及整体用户体验。

有助于网站的 SEO 性能

面包屑不仅有利于用户体验,而且对 Google 排名也有重大影响。对于那些不知道的人,Google 使用面包屑对内容进行分类和上下文关联。

换句话说,面包屑向搜索引擎显示该网站的结构。这对于 SEO 来说是双赢,因为面包屑会直接影响:

  • 用户如何在您的网站上查找信息,从而提高网络可用性
  • 搜索引擎如何对您的网站编制索引并确定您的网站在 Google 上的排名

从SEO优化的角度来看,面包屑无疑是一个多功能工具。

如何在 Magento 2 中向 CMS 页面显示面包屑

  1. 在 Magento 2 管理面板上,单击商店。在设置部分中,选择配置
  2. 在左侧面板的“常规”下,选择“Web”
  3. 打开默认页面部分。
  4. 将CMS 页面的显示面包屑更改为 *Yes
  5. 完成后,单击“保存配置”
]]>
Wed, 28 Feb 2024 07:38:51 +0000
<![CDATA[Magento2如何获取浏览量最高的产品]]> https://www.360magento.com/blog/get-most-viewed-product-collection-magento/ 展示浏览次数最多的产品通常用于吸引客户使用该产品,也可以作为对他们的推荐。这个浏览次数最多的产品系列对于对商店中销售的产品不太了解的首次访问用户特别有帮助。它可以帮助他们更轻松地选择最好的商品。

浏览次数最多的产品在帮助您的商店提高销量方面发挥着重要作用。这是因为在您的网站上展示这些产品可以引导客户收集最有趣的产品,而不是让他们毫无方向地闲逛。但是,要显示浏览次数最多的产品,您需要获取浏览次数最多的产品集合。因此,在今天的文章中,我将指导您如何在 Magento 2 中获得浏览次数最多的产品集合

获取浏览次数最多的产品系列的 3 个步骤

  • 第 1 步:创建 MostViewedProducts 块
  • 第 2 步:插入phtml文件
  • 第 3 步:刷新缓存和测试结果

第 1 步:创建 MostViewedProducts 块

要获得浏览次数最多的产品集合,首先,您需要创建一个MostViewedProducts块。为此,请按照路径Example/Productslider/Block/MostViewedProducts.php添加以下代码:

<?php

namespace Example\Productslider\Block;
use Magento\Catalog\Block\Product\Context;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\App\Http\Context as HttpContext;
use Magento\Framework\Stdlib\DateTime\DateTime;
use Mageplaza\Productslider\Helper\Data;
use Example\Productslider\Model\ResourceModel\Report\Product\CollectionFactory as MostViewedCollectionFactory;
/**
 * Class MostViewedProducts
 * @package Mageplaza\Productslider\Block
 */
class MostViewedProducts extends AbstractSlider
{
    /**
     * @var MostViewedCollectionFactory
     */
    protected $_mostViewedProductsFactory;
    /**
     * MostViewedProducts constructor.
     * @param Context $context
     * @param CollectionFactory $productCollectionFactory
     * @param Visibility $catalogProductVisibility
     * @param DateTime $dateTime
     * @param Data $helperData
     * @param HttpContext $httpContext
     * @param MostViewedCollectionFactory $mostViewedProductsFactory
     * @param array $data
     */
    public function __construct(
        Context $context,
        CollectionFactory $productCollectionFactory,
        Visibility $catalogProductVisibility,
        DateTime $dateTime,
        Data $helperData,
        HttpContext $httpContext,
        MostViewedCollectionFactory $mostViewedProductsFactory,
        array $data = []
    ) {
        $this->_mostViewedProductsFactory = $mostViewedProductsFactory;
        parent::__construct($context, $productCollectionFactory, $catalogProductVisibility, $dateTime, $helperData, $httpContext, $data);
    }
    /**
     * Get Product Collection of MostViewed Products
     * @return mixed
     */
    public function getProductCollection()
    {
        $collection = $this->_mostViewedProductsFactory->create()
            ->addAttributeToSelect('*')
            ->setStoreId($this->getStoreId())->addViewsCount()
            ->addStoreFilter($this->getStoreId())
            ->setPageSize($this->getProductsCount());
        return $collection;
    }
}

第 2 步:插入phtml文件

在块中拥有集合后,现在您可以按照此代码片段从块中获取产品集合Example/HelloWorld/view/frontend/templates/list.phtml

接下来,请在phtml文件中插入以下代码

<?php
$collection = $block->getProductCollection();
foreach ($collection as $_product) {
    echo $product->getName() . ' - ' . $product->getProductUrl() . '<br />';
}

第 3 步:刷新缓存和测试结果

最后,让我们刷新缓存并测试结果。

]]>
Thu, 22 Feb 2024 07:13:32 +0000
<![CDATA[使用Magento 2 API获取所有产品、订单和类别的指南]]> https://www.360magento.com/blog/get-all-products-orders-categories-magento2/ Magento是一款功能强大的电子商务平台,提供了强大的API来与其进行集成。通过Magento 2 API,您可以轻松地获取产品、订单和类别等信息,从而实现各种自动化和定制化的功能。本文将介绍如何使用Magento 2 API来获取所有产品、订单和类别的方法。

1. 准备工作

首先,您需要确保您有一个Magento 2的实例,并且已经配置了API访问权限。在Magento 2的后台管理界面中,您可以通过以下步骤配置API访问权限:

  • 登录Magento 2后台管理界面。
  • 转到“系统” -> “集成API”。
  • 确保已启用API,并创建一个新的集成。

创建集成后,您将获得一个访问令牌,用于通过API进行身份验证。

2. 使用API获取产品信息

要获取所有产品的信息,您可以使用Magento 2的catalogProductRepositoryV1端点。您可以发送一个GET请求到以下端点:

http://yourmagento2domain.com/rest/V1/products

确保在请求头中包含正确的身份验证信息,使用您的访问令牌进行身份验证。这将返回包含所有产品信息的JSON响应。

3. 使用API获取订单信息

要获取所有订单的信息,您可以使用Magento 2的salesOrderRepositoryV1端点。发送GET请求到以下端点:

http://yourmagento2domain.com/rest/V1/orders

同样,请确保在请求头中包含正确的身份验证信息。响应将包含所有订单的详细信息。

4. 使用API获取类别信息

要获取所有类别的信息,您可以使用Magento 2的catalogCategoryManagementV1端点。发送GET请求到以下端点:

http://yourmagento2domain.com/rest/V1/categories

同样,不要忘记在请求头中包含身份验证信息。响应将包含所有类别的详细信息。

5. 示例代码

以下是一个简单的Python示例代码,演示如何使用requests库来通过Magento 2 API获取产品、订单和类别信息:

python
import requests # 设置Magento 2的API端点和访问令牌
base_url = "http://yourmagento2domain.com/rest/V1/"
token = "your_access_token" # 获取所有产品信息
product_url = base_url + "products" product_response = requests.get(product_url, headers={"Authorization": "Bearer " + token})
products = product_response.json() print("Products:", products) # 获取所有订单信息
order_url = base_url + "orders"
order_response = requests.get(order_url, headers={"Authorization": "Bearer " + token})
orders = order_response.json() print("Orders:", orders) # 获取所有类别信息
category_url = base_url + "categories"
category_response = requests.get(category_url, headers={"Authorization": "Bearer " + token})
categories = category_response.json()
print("Categories:", categories)
]]>
Mon, 19 Feb 2024 07:02:00 +0000
<![CDATA[如何在 Magento 2 中更改 Favicon]]> https://www.360magento.com/blog/how-upload-favicon-magento/ 在Magento 2中更改站点的favicon是一个相对简单的过程,您可以通过以下步骤完成。在这篇博文中,我将指导您如何更改Magento 2站点的favicon。

步骤 1:准备favicon图标

首先,您需要准备好要用作favicon的图标。通常,这是一个ICO格式的图标文件,建议大小为16x16像素或32x32像素。您可以使用图标制作工具或在线图标生成器来创建favicon。

步骤 2:上传favicon图标到Magento 2

  1. 将favicon图标上传到Magento 2的您的主题目录中。您的主题目录通常位于app/design/frontend/Your_Vendor/Your_Theme

  2. 将favicon图标放置在您的主题目录的web子目录中。如果web子目录不存在,请创建它。

步骤 3:更新Magento 2配置

  1. 登录到Magento 2后台管理面板。

  2. 转到“内容(Content)” > “配置(Configuration)” > “设计(Design)”。

  3. 在“HTML头部(HTML Head)”部分,找到“Favicon图标(Favicon Icon)”字段。

  4. 在“Favicon图标(Favicon Icon)”字段中输入您的favicon图标的URL。例如,如果您的主题目录是app/design/frontend/Your_Vendor/Your_Theme,而您的favicon图标名为favicon.ico,则输入Your_Vendor/Your_Theme/favicon.ico

  5. 保存配置更改。

步骤 4:清除缓存并刷新页面

在Magento 2中更新任何配置后,都应该清除缓存以确保更改生效。完成后,刷新您的Magento 2网站页面,您应该能够看到新的favicon图标已经生效了。

]]>
Sun, 18 Feb 2024 07:52:59 +0000
<![CDATA[如何在 Magento 2 中添加新的 CMS 块]]> https://www.360magento.com/blog/how-to-add-new-cms-blocks-magento/ Magento 2的CMS块(Content Management System Blocks)是一种方便的方式,可以在网站的不同位置添加自定义内容,而无需深度的编码知识。以下是在Magento 2中添加新的CMS块的详细步骤:

步骤 1:登录Magento后台

通过浏览器访问Magento 2后台,输入管理员用户名和密码,登录到Magento管理面板。

步骤 2:进入CMS块管理页面

在Magento管理面板的左侧导航栏中,找到并点击“Content”(内容),然后选择“Elements”(元素)下的“Blocks”(块)。

步骤 3:创建新CMS块

在“Blocks”页面上,点击右上角的“Add New Block”(添加新块)按钮。

步骤 4:填写CMS块信息

在“Block Information”(块信息)页面上,填写以下信息:

  • Block Title(块标题): 输入CMS块的标题。
  • Identifier(标识符): 输入唯一的标识符,通常是小写字母和下划线的组合,用于在代码中引用CMS块。
  • Store View(商店视图): 选择CMS块要适用的商店视图。
  • Content(内容): 在文本编辑器中输入CMS块的内容,您可以使用HTML标记自定义格式。

步骤 5:设置CMS块的显示与隐藏

在“Block Information”页面的右上角,您可以选择CMS块的状态:

  • Enable Block(启用块): 将其设置为“Yes”(是)以启用CMS块。
  • Hide from Navigation (在导航中隐藏): 将其设置为“Yes”(是)以在导航中隐藏CMS块。

步骤 6:保存CMS块

点击页面右上角的“Save Block”(保存块)按钮,以保存新创建的CMS块。

步骤 7:清理缓存

在Magento 2中,配置更改后通常需要清理缓存。在Magento管理面板的左侧导航栏中,选择“System”(系统)下的“Cache Management”(缓存管理)。然后,点击“Flush Magento Cache”(清除Magento缓存)以确保新的配置生效。

步骤 8:在页面或布局中调用CMS块

在您希望显示CMS块的页面或布局文件中,您可以使用以下代码调用CMS块:

your_block_identifier替换为您在第4步中设置的标识符。

]]>
Mon, 12 Feb 2024 07:28:41 +0000
<![CDATA[如何在 Magento 2 中添加、删除、管理客户评论和评级?]]> https://www.360magento.com/blog/how-manage-review-rating-magento/ 步骤 1:登录Magento后台

通过浏览器访问Magento 2后台,输入管理员用户名和密码,登录到Magento管理面板。

步骤 2:添加客户评论和评级

在Magento管理面板的左侧导航栏中,找到并点击“Marketing”(营销),然后选择“User Content”(用户内容)下的“Reviews and Ratings”(评论和评级)。

  • 添加新评论:
    • 点击“Customer Reviews”(客户评论)。
    • 点击右上角的“Add New Review”(添加新评论)按钮。
    • 选择要评价的产品,填写评分和评论信息。
    • 点击“Save Review”(保存评论)。

步骤 3:管理评论和评级

  • 查看和编辑评论:
    • 在“Customer Reviews”页面,您可以查看所有评论和评级。
    • 点击要编辑的评论,进行相应的修改。
    • 点击“Save Review”(保存评论)以保存更改。

步骤 4:删除评论和评级

  • 删除评论:
    • 在“Customer Reviews”页面,找到要删除的评论。
    • 选择评论并点击右上角的“Delete”(删除)按钮。
    • 确认删除。

步骤 5:管理评级选项

在Magento管理面板的左侧导航栏中,找到并点击“Stores”(商店),然后选择“Configuration”(配置)。在“Catalog”(目录)下的“Product Reviews”(产品评论)中,您可以配置有关评论和评级的各种选项。

  • 启用/禁用评论:

    • 在“Product Reviews”页面,找到“General Settings”(常规设置)部分。
    • 将“Enabled”(启用)设置为“Yes”(是)以启用评论功能,设置为“No”(否)以禁用。
  • 审核评论:

    • 在“Product Reviews”页面,找到“Product Review Approval”(产品评论批准)部分。
    • 将“New Reviews”(新评论)设置为“Approved”(批准)或“Pending”(待定)。

步骤 6:清理缓存

在Magento 2中,配置更改后通常需要清理缓存。在Magento管理面板的左侧导航栏中,选择“System”(系统)下的“Cache Management”(缓存管理)。然后,点击“Flush Magento Cache”(清除Magento缓存)以确保新的配置生效。

注意事项:

  1. 审慎删除评论: 在删除评论之前,请确保您真的需要删除它们,并且了解删除评论可能对客户信任和购买决策产生的影响。

  2. 定期审核: 定期审核和回复评论,以维护积极的在线社区和客户关系。

]]>
Sun, 11 Feb 2024 08:25:54 +0000
<![CDATA[在Magento 2中更改商店电子邮件地址的详细步骤]]> https://www.360magento.com/blog/how-change-store-email-addresses-magento/ 通过浏览器访问Magento 2后台,输入管理员用户名和密码,登录到Magento管理面板。

步骤 2:进入系统配置

在Magento管理面板的左侧导航栏中,找到并点击“Stores”(商店),然后选择“Configuration”(配置)。

步骤 3:配置Store Email Addresses

在“Configuration”页面上,展开“General”(常规)并选择“Store Email Addresses”(商店电子邮件地址)。

步骤 4:更新General Contact(一般联系)地址

在“Store Email Addresses”页面上,您将看到“General Contact”(一般联系)部分。在这里,您可以更改与一般店铺联系相关的电子邮件地址。

  • Sender Name: 输入显示为邮件发送者的名称。
  • Sender Email: 输入商店的一般联系电子邮件地址。

步骤 5:更新Sales Representative(销售代表)地址(可选)

如果您的商店需要与销售相关的电子邮件通知,您可以在“Sales Representative”(销售代表)部分更新相关信息。

  • Sender Name: 输入显示为邮件发送者的名称。
  • Sender Email: 输入销售代表的电子邮件地址。

步骤 6:更新Customer Support(客户支持)地址(可选)

如果您的商店提供客户支持,您可以在“Customer Support”(客户支持)部分更新相关信息。

  • Sender Name: 输入显示为邮件发送者的名称。
  • Sender Email: 输入客户支持的电子邮件地址。

步骤 7:保存配置更改

点击页面右上角的“Save Config”(保存配置)按钮,以保存对商店电子邮件地址的更改。

步骤 8:清理缓存

]]>
Sat, 10 Feb 2024 07:15:25 +0000
<![CDATA[如何在 Magento 2 中更改 Favicon]]> https://www.360magento.com/blog/how-upload-favicon-magento-2/ Favicon是显示在浏览器标签页和书签上的小图标,对于网站来说是一个重要的视觉元素。在Magento 2中,更改Favicon是一项简单的任务,以下是详细的步骤:

步骤 1:准备Favicon图标

首先,准备一个正方形的图标,通常推荐大小为16x16像素或32x32像素。确保图标的文件格式为.ico(Windows图标格式)或.png。

步骤 2:上传Favicon图标

将准备好的Favicon图标上传到Magento 2的媒体文件夹。您可以使用FTP或Magento后台的媒体库来完成此操作。推荐将图标命名为favicon.ico以确保兼容性。

步骤 3:登录Magento后台

通过浏览器访问Magento 2后台,输入管理员用户名和密码,登录到Magento管理面板。

步骤 4:进入主题配置

在Magento管理面板的左侧导航栏中,找到并点击“Content”(内容),然后选择“Configuration”(配置)。

步骤 5:选择当前主题

在“Configuration”页面上,找到您当前使用的主题。在“Themes”部分,展开当前主题的选项。

步骤 6:配置Favicon设置

在当前主题的选项下,找到“Favicon”部分。在“Favicon Icon”字段中,输入您上传的Favicon图标的路径。例如,如果您上传的图标在/media/favicon.ico,则在该字段中输入/media/favicon.ico

步骤 7:保存配置更改

点击页面右上角的“Save Config”(保存配置)按钮,以保存对Favicon的更改。

步骤 8:清理缓存

在Magento 2中,配置更改后通常需要清理缓存。在Magento管理面板的左侧导航栏中,选择“System”(系统)下的“Cache Management”(缓存管理)。然后,点击“Flush Magento Cache”(清除Magento缓存)以确保新的配置生效。

步骤 9:刷新浏览器缓存

刷新您的浏览器缓存,或者在浏览器中打开一个新的标签页,以查看更改后的Favicon。

]]>
Fri, 09 Feb 2024 07:12:32 +0000
<![CDATA[在Magento 2中将小部件插入侧边栏的详细步骤]]> https://www.360magento.com/blog/how-to-insert-a-widget-into-sidebar-magento/ 在Magento 2中,使用小部件(Widget)是一种方便的方法,可以在网站的侧边栏中添加各种自定义内容,例如广告、促销信息或其他相关信息。以下是在Magento 2中将小部件插入侧边栏的步骤:

步骤 1:登录Magento后台

在您的Magento 2安装目录中,通过浏览器访问Magento后台。输入管理员用户名和密码,登录到Magento管理面板。

步骤 2:创建小部件

在Magento管理面板的左侧导航栏中,找到并点击“Content”(内容),然后选择“Widgets”(小部件)。

在“Widgets”页面上,点击右上角的“Add Widget”(添加小部件)按钮。

步骤 3:选择小部件类型

在“Type”(类型)下拉菜单中,选择要插入侧边栏的小部件类型。通常,您可以选择“CMS Static Block”(CMS静态块)或其他适合您需求的小部件类型。

步骤 4:配置小部件参数

根据所选小部件类型,您将看到不同的配置选项。例如,如果选择“CMS Static Block”(CMS静态块),您需要选择要显示的静态块。

填写所需的配置信息,确保选择正确的Store View(商店视图),然后点击“Save and Continue Edit”(保存并继续编辑)。

步骤 5:指定布局更新

在左侧导航栏中,选择“Layout Updates”(布局更新)。然后,点击“Add Layout Update”(添加布局更新)按钮。

在“Display On”(显示在)下拉菜单中,选择“Specified Page”(指定页面),并选择您希望小部件显示的页面。

步骤 6:保存小部件配置

点击页面右上角的“Save”(保存)按钮,以保存小部件的配置。

步骤 7:清理缓存

在Magento 2中,配置更改后通常需要清理缓存。在Magento管理面板的左侧导航栏中,选择“System”(系统)下的“Cache Management”(缓存管理)。然后,点击“Flush Magento Cache”(清除Magento缓存)以确保新的配置生效。

步骤 8:刷新前端页面

刷新您的网站前端页面,您将看到已添加的小部件显示在指定的侧边栏位置上。

]]>
Thu, 08 Feb 2024 07:11:28 +0000
<![CDATA[在Magento 2中启用模板路径提示的详细步骤]]> https://www.360magento.com/blog/how-to-enable-template-path-hints-magento/ Magento 2提供了一种方便的开发工具,即模板路径提示,它可以在前端页面上显示每个块的模板路径。以下是在Magento 2中启用和使用模板路径提示的步骤:

步骤 1:登录Magento后台

在您的Magento 2安装目录中,通过浏览器访问Magento后台。输入管理员用户名和密码,登录到Magento管理面板。

步骤 2:进入系统配置

在Magento管理面板的左侧导航栏中,找到并点击“Stores”(商店)下的“Configuration”(配置)选项。

步骤 3:配置Developer模式

在“Configuration”页面上,左侧导航栏中展开“Advanced”(高级)并选择“Developer”(开发者)。

  • 在“Debug”(调试)部分,将“Enabled Template Path Hints for Storefront”(在商店前端启用模板路径提示)设置为“Yes”(是)。
  • 将“Enabled Template Path Hints for Admin”(在管理后台启用模板路径提示)设置为“Yes”(是)。

步骤 4:配置Developer Client Restrictions(可选)

在“Developer”页面上,继续滚动到“Developer Client Restrictions”部分。

  • 如果您想仅在特定IP地址上显示模板路径提示,将“Allowed IPs (comma-separated)”(允许的IP地址,用逗号分隔)设置为相应的IP地址。

步骤 5:保存配置更改

点击页面右上角的“Save Config”(保存配置)按钮,以保存对系统配置的更改。

步骤 6:清理缓存

在Magento 2中,配置更改后通常需要清理缓存。在Magento管理面板的左侧导航栏中,选择“System”(系统)下的“Cache Management”(缓存管理)。然后,点击“Flush Magento Cache”(清除Magento缓存)以确保新的配置生效。

步骤 7:刷新前端页面

在前端页面上,刷新浏览器,您将看到每个块的模板路径提示。

]]>
Wed, 07 Feb 2024 08:03:48 +0000
<![CDATA[在Magento 2中启用CSS和JavaScript文件合并的步骤]]> https://www.360magento.com/blog/how-to-enable-merge-css-javascript-magento/ Magento 2允许您通过合并CSS和JavaScript文件来减少HTTP请求,从而提高页面加载速度。以下是在Magento 2中启用此功能的步骤:

步骤 1:登录Magento后台

在您的Magento 2安装目录中,通过浏览器访问Magento后台。输入管理员用户名和密码,登录到Magento管理面板。

步骤 2:进入系统配置

在Magento管理面板的左侧导航栏中,找到并点击“Stores”(商店)下的“Configuration”(配置)选项。

步骤 3:配置CSS合并

在“Configuration”页面上,左侧导航栏中展开“Advanced”(高级)并选择“Developer”(开发者)下的“CSS Settings”(CSS设置)。

  • 将“Merge CSS Files”(合并CSS文件)设置为“Yes”(是)。
  • 将“Minify CSS Files”(压缩CSS文件)设置为“Yes”(是)(可选)。
  • 将“Generate Source Maps”(生成源映射)设置为“Yes”(是)(可选)。

步骤 4:配置JavaScript合并

在“Developer”页面上,继续滚动到“JavaScript Settings”(JavaScript设置)部分。

  • 将“Enable JavaScript Bundling”(启用JavaScript捆绑)设置为“Yes”(是)。
  • 将“Minify JavaScript Files”(压缩JavaScript文件)设置为“Yes”(是)(可选)。
  • 将“Enable JavaScript Source Maps”(启用JavaScript源映射)设置为“Yes”(是)(可选)。

步骤 5:保存配置更改

点击页面右上角的“Save Config”(保存配置)按钮,以保存对系统配置的更改。

步骤 6:清理缓存

在Magento 2中,配置更改后通常需要清理缓存。在Magento管理面板的左侧导航栏中,选择“System”(系统)下的“Cache Management”(缓存管理)。然后,点击“Flush Magento Cache”(清除Magento缓存)以确保新的配置生效。

]]>
Tue, 06 Feb 2024 03:59:56 +0000
<![CDATA[如何在 Magento 2 中启用客户登录/注册验证码]]> https://www.360magento.com/blog/how-to-enable-customer-login-register-captcha-magento/ 启用验证码是一项有效的安全措施,可以防止自动化攻击和恶意注册。在Magento 2中,您可以通过以下步骤启用客户登录和注册时的验证码:

步骤 1:登录Magento后台

在您的Magento 2安装目录中,通过浏览器访问Magento后台。输入管理员用户名和密码,登录到Magento管理面板。

步骤 2:进入系统配置

在Magento管理面板的左侧导航栏中,找到并点击“Stores”(商店)下的“Configuration”(配置)选项。

步骤 3:配置验证码设置

在“Configuration”页面上,左侧导航栏中展开“Customers”(客户)并选择“Customer Configuration”(客户配置)。

  • 在“Create New Account Options”(创建新帐户选项)下,将“Enable CAPTCHA on Storefront”(在商店前端启用验证码)设置为“Yes”(是)。
  • 在“Login Options”(登录选项)下,将“Enable CAPTCHA in Admin”(在管理后台启用验证码)设置为“Yes”(是)(可选)。

步骤 4:选择验证码类型

在“Customer Configuration”页面上,继续滚动到“CAPTCHA”部分。

  • 在“Forms”(表单)下,选择要启用验证码的表单,例如“Create User”(创建用户)和“Login”(登录)。
  • 在“Displaying Mode”(显示模式)下,选择“Always”(始终)或“After Number of Attempts to Login”(登录尝试次数后)。

步骤 5:保存配置更改

点击页面右上角的“Save Config”(保存配置)按钮,以保存对系统配置的更改。

步骤 6:清理缓存

在Magento 2中,配置更改后通常需要清理缓存。在Magento管理面板的左侧导航栏中,选择“System”(系统)下的“Cache Management”(缓存管理)。然后,点击“Flush Magento Cache”(清除Magento缓存)以确保新的配置生效。

]]>
Mon, 05 Feb 2024 07:00:48 +0000
<![CDATA[在Magento 2中启用单一商店模式的步骤和注意事项]]> https://www.360magento.com/blog/how-enable-single-store-mode-magento-2/ Magento 2 默认以多商店模式运行,这意味着您可以在一个Magento实例中管理多个商店。但在某些情况下,可能需要将系统配置为单一商店模式,特别是在只需要一个商店的情况下。以下是在Magento 2中启用单一商店模式的步骤:

步骤 1:登录Magento后台

在您的Magento 2安装目录中,通过浏览器访问Magento后台。输入管理员用户名和密码,登录到Magento管理面板。

步骤 2:进入系统配置

在Magento管理面板的左侧导航栏中,找到并点击“Stores”(商店)下的“Configuration”(配置)选项。

步骤 3:选择单一商店模式

在“Configuration”页面上,左侧导航栏中展开“General”(常规)并选择“General”下的“Single-Store Mode”(单一商店模式)。

步骤 4:启用单一商店模式

在“Single-Store Mode”选项中,将“Enable Single-Store Mode”(启用单一商店模式)设置为“Yes”(是)。

步骤 5:保存配置更改

点击页面右上角的“Save Config”(保存配置)按钮,以保存对系统配置的更改。

步骤 6:清理缓存

在Magento 2中,配置更改后通常需要清理缓存。在Magento管理面板的左侧导航栏中,选择“System”(系统)下的“Cache Management”(缓存管理)。然后,点击“Flush Magento Cache”(清除Magento缓存)以确保新的配置生效。

注意事项:

  1. 备份数据库和文件: 在进行系统配置更改之前,请务必备份Magento数据库和文件。这样可以在发生意外情况时恢复系统状态。

  2. 检查扩展和主题兼容性: 一些Magento扩展和主题可能依赖于多商店模式,因此在切换到单一商店模式之前,请确保您使用的扩展和主题与该模式兼容。

  3. 审查网站链接: 在单一商店模式下,网站链接的结构可能会发生变化。确保在更改模式后,您的网站链接仍然正常工作,以避免SEO和用户体验方面的问题。

  4. 测试功能和购物流程: 在切换到单一商店模式后,仔细测试您的网站功能和购物流程,确保一切正常运作。

]]>
Sun, 04 Feb 2024 08:55:13 +0000
<![CDATA[创建新的 Magento 2 管理员用户]]> https://www.360magento.com/blog/how-to-create-new-admin-user-magento-2/ 通过命令行创建 Magento 2 管理员帐户

创建管理员帐户/用户的另一种方法是,我们可以通过命令行(cli)创建新的管理员用户。以下是具体操作方法。

转到 Magento 2 根文件夹,运行创建一个新的管理员用户命令行:

php bin/magento admin:user:create

它会询问您:用户名、密码、电子邮件、名字和姓氏。

这是我们填写的内容:

Admin user: YourName
Admin password: YourPassword
Admin email: YourName@email.com
Admin first name: YourName
Admin last name: Team

并得到结果:

Created Magento administrator user named YourName
]]>
Sat, 03 Feb 2024 07:51:18 +0000
<![CDATA[Magento 2 缓存管理:12 种缓存类型]]> https://www.360magento.com/blog/10-cache-types-how-manage-cache-magento-2/
12 Magento 2 缓存类型

具体来说,Cache的不同类别是:

  • Configuration (config):调整配置文件后,需要刷新它们,包括配置并存储特定设置
  • Layouts (layout):调整布局文件后,需要刷新它们,包括所有组件中编译后的页面布局
  • Blocks HTML output (block_html):调整视图层后,需要刷新它们,包括每个块的页面片段
  • Collections Data (collections):通过Magento,它可以自动刷新数据库查询。但是,自定义模块可能会写入导致 Magento 无法自行清理的条目,以防 Magento 无法清理,因此我们需要清理缓存
  • Reflection Data (reflection):API接口反射数据将被刷新
  • Database DDL operations (db_ddl):它可以由Magento自动刷新,但第3方可以在对 进行自定义更改后添加更多数据,database schema这可以清理缓存
  • EAV types and attributes (eav):将有关实体属性的元数据放入缓存中,一般情况下不应该刷新缓存
  • Integrations Configuration (config_integration):在您的商店中缓存已编译的集成。添加新的或更改现有的集成后进行清理
  • Integrations API Configuration (config_integration_api):商店集成的编译集成API配置
  • Page Cache (full_page):此缓存链接 HTML 页面,因此有必要定期清理此类缓存
  • Translations (translate):合并所有模块的翻译后,合并缓存将被清除
  • Web Services Configuration (config_webservice): 缓存Web API Structure
]]>
Fri, 02 Feb 2024 07:48:54 +0000
<![CDATA[Magento开发中的10个小技巧,让您的项目更高效]]> https://www.360magento.com/blog/magento-dev-totips/
  • 使用代码段(Snippets)提高效率: 利用您的IDE(集成开发环境)或编辑器中的代码段功能,预定义一些常用的Magento代码片段,如创建新模块、添加布局文件等。这样可以加快编码速度,减少重复性劳动。

  • 使用Magento命令行工具: Magento命令行工具(CLI)提供了许多有用的命令,如清理缓存、重建索引、安装模块等。熟练使用这些命令可以在开发过程中省时省力。

  • 启用开发者模式: 在开发环境中启用Magento的开发者模式,这可以提供更详细的错误报告和调试信息。在app/bootstrap.php文件中设置MAGENTO_MODEdeveloper即可。

    1. 使用Xdebug进行调试: 集成Xdebug来进行代码调试,这样可以更轻松地识别和解决问题。配置您的IDE以与Xdebug一起使用,并设置断点进行逐步调试。

    2. 定期清理日志和临时文件: 定期清理Magento的日志文件和临时文件,以保持系统性能。您可以设置定时任务或使用Magento命令行工具来自动执行这些清理操作。

    3. 了解Magento事件(Events): 使用Magento的事件体系,它允许您在系统的不同部分插入自定义代码。这是扩展Magento功能的强大方式,同时保持模块的松耦合性。

    4. 优化数据库查询: 编写高效的数据库查询是关键之一。使用Magento的数据库抽象层和索引,避免使用直接SQL查询,以确保查询的效率和可维护性。

    5. 使用布局和块缓存: 利用Magento的布局和块缓存,减少页面加载时间。了解何时使用缓存,以及如何在需要时清除缓存,有助于提高网站性能。

    6. 合理使用Magento UI组件: Magento的UI组件提供了丰富的前端功能。了解如何正确使用这些组件,以及如何根据项目需要进行自定义,可以使您的前端开发更加灵活。

    7. 版本控制和部署策略: 使用版本控制系统(如Git)来管理您的Magento项目。定义清晰的部署策略,包括配置文件、数据库迁移等,以确保在不同环境中的一致性。

    结论: 这些小技巧可能看似微不足道,但在Magento开发过程中,它们可以累积成为提高效率和代码质量的关键因素。通过灵活运用这些技巧,您将更轻松地应对各种开发挑战,提升Magento项目的成功实施。

    ]]>
    Thu, 01 Feb 2024 07:36:26 +0000
    <![CDATA[Magento2的最新技术趋势]]> https://www.360magento.com/blog/magento-new-technology-trends/ 尊敬的Magento2开发者们,

    欢迎回到我们的博客!今天,我们将深入探讨Magento2的一些最新技术趋势,帮助您更好地了解如何提升您的开发效率和用户体验。让我们一起来看看吧!

    1. Magento PWA Studio的崭新体验

    随着移动设备在电商中的重要性不断增加,Magento PWA Studio成为开发者们的热门选择。采用渐进式Web应用程序(PWA)的理念,Magento PWA Studio能够提供更快速、流畅的用户体验,并在各种设备上保持一致性。我们建议您深入研究并考虑在您的项目中采用PWA技术,以提高网站性能和用户满意度。

    2. Magento Cloud的便捷部署与扩展性

    随着云计算的普及,Magento Cloud提供了一种简化部署和扩展性的解决方案。借助云服务,您可以轻松部署、管理和扩展您的Magento2实例,同时受益于高级安全性和性能优化。我们建议您考虑将您的Magento2项目迁移到云平台,以获得更灵活的扩展和更好的性能。

    3. GraphQL的数据查询灵活性

    Magento2引入了GraphQL,这是一种强大的数据查询语言,能够帮助您更精准地获取所需的数据,减少不必要的负载。通过合理利用GraphQL,您可以提高数据查询的效率,并为客户提供更快速的响应时间。在您的开发过程中,尝试使用GraphQL来优化数据获取流程,提升网站性能。

    4. Magento2.4.x的安全更新

    安全始终是我们开发者关注的焦点。确保您的Magento2实例始终更新到最新版本,以获取最新的安全补丁和功能改进。Magento2.4.x系列引入了一系列安全性增强措施,包括CSRF攻击防护和更强大的身份验证机制。保持更新,是确保您的网站安全的关键步骤。

    ]]>
    Thu, 18 Jan 2024 08:44:40 +0000
    <![CDATA[magento2 中 ngnix 配置多站点]]> https://www.360magento.com/blog/magento2-ngnix-config/ 在 Magento 2 中,配置多站点(Multi-Store)需要特殊的 Nginx 配置,因为 Magento 2 支持在同一个安装中运行多个站点。以下是一个简单的示例,假设您有两个站点,分别是 site1.com 和 site2.com:

    server {
        listen 80;
        server_name site1.com www.site1.com;
    
        set $MAGE_ROOT /path/to/magento2;
        set $MAGE_MODE production;
    
        include /path/to/magento2/nginx.conf.sample;
    }
     
    server {
        listen 80;
        server_name site2.com www.site2.com;
    
        set $MAGE_ROOT /path/to/magento2;
        set $MAGE_MODE production;
    
        include /path/to/magento2/nginx.conf.sample;
    }
    

    在这个配置中,每个 server 块对应一个站点,通过 server_name 指定了该 server 块所处理的域名。

    请将 /path/to/magento2 替换为您 Magento 2 安装的实际路径。并确保 Nginx 配置文件 /path/to/magento2/nginx.conf.sample 存在并包含 Magento 2 的相关配置。

    Magento 2 通常附带一个名为 nginx.conf.sample 的示例配置文件,您可以在 Magento 安装目录的 pub 子目录下找到它。确保配置文件中的 fastcgi_pass 和其他相关设置正确指向您的 Magento 2 安装。

    最后,确保每个域名的 DNS 记录正确指向您的服务器 IP 地址。配置完成后,重新加载或重启 Nginx 使配置生效。

    ]]>
    Wed, 17 Jan 2024 08:00:00 +0000
    <![CDATA[Magento2 中ngnix 和Apache 配置 ]]> https://www.360magento.com/blog/magento2-web-ngnix-apach/ 在 Magento 2 中,您可以选择使用 Nginx 或 Apache 作为 web 服务器。以下是简单的示例配置,分别适用于 Nginx 和 Apache。

    Nginx 配置示例:

    server {
        listen 80;
        server_name your_domain.com www.your_domain.com;
    
        set $MAGE_ROOT /path/to/your/magento2;
        set $MAGE_MODE production;
    
        include /path/to/your/magento2/nginx.conf.sample;
    }
    

    请将 /path/to/your/magento2 替换为您 Magento 2 安装的实际路径。确保 Nginx 配置文件 /path/to/your/magento2/nginx.conf.sample 存在并包含 Magento 2 的相关配置。

    Apache 配置示例:

    <VirtualHost *:80>
    ServerAdmin webmaster@your_domain.com
    DocumentRoot "/path/to/your/magento2"
    ServerName your_domain.com
    ServerAlias www.your_domain.com

    <Directory "/path/to/your/magento2">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
    </Directory>

    ErrorLog "/var/log/apache2/your_domain_error.log"
    CustomLog "/var/log/apache2/your_domain_access.log" combined
    </VirtualHost>

    同样,请将 /path/to/your/magento2 替换为您 Magento 2 安装的实际路径。确保 Apache 的虚拟主机配置文件包含了必要的设置,如 AllowOverride All 以启用 .htaccess 文件。

    在上述配置中,您需要确保 Nginx 或 Apache 的配置正确指向 Magento 2 的安装目录,并且相关的访问和错误日志路径是正确的。

    此外,如果您有多个站点(Multi-Store)需要配置,请根据具体情况修改上述配置文件,并确保 Magento 2 的配置文件(如 nginx.conf.sample)中也正确设置了站点信息。

    配置完成后,请重新加载或重启相应的 web 服务器,以使配置生效。

    
    
    ]]>
    Tue, 16 Jan 2024 03:22:34 +0000
    <![CDATA[Magento 未来趋势]]> https://www.360magento.com/blog/magento-future-trends/ Magento作为一流的电商平台,一直在不断演进以适应市场和技术的变化。在这篇文章中,我们将深入研究Magento未来的趋势,以及在下一代电商体验中将会迎来的创新和变革。

    1. 头脑购物体验

    未来的Magento电商平台将更加注重提供头脑购物(Mindful Shopping)体验。这包括通过人工智能和个性化推荐系统,更深入地了解用户需求,提供更符合其兴趣和偏好的产品。

    2. 增强现实(AR)和虚拟现实(VR)整合

    Magento将更多地整合增强现实和虚拟现实技术,为用户提供更丰富的购物体验。通过AR,用户可以在实际环境中预览产品,而VR则为他们提供沉浸式的虚拟商店体验。

    3. 社交购物整合

    未来的Magento将更深度地整合社交媒体和购物体验。用户可以直接在社交平台上发现产品并完成购买,同时商家可以通过社交媒体建立更紧密的客户关系。

    4. 可持续和负责任的电商

    Magento未来将更加关注可持续和负责任的电商实践。这包括推动供应链的可追溯性、提供环保选项以及支持社会责任项目。这样的做法将有助于塑造品牌形象,吸引越来越注重可持续性的消费者。

    5. 无缝跨渠道体验

    Magento未来版本将进一步提升跨渠道购物的无缝体验。无论用户是通过电脑、平板还是手机,他们都能够享受一致的购物体验,从而提高用户忠诚度和购物转化率。

    6. 智能物流和快速交付

    未来Magento将更加注重智能物流系统,通过实时数据和智能算法提高物流效率。同时,支持更快速和可靠的配送方式,以满足用户对于即时交付的需求。

    ]]>
    Mon, 15 Jan 2024 08:36:18 +0000
    <![CDATA[Magento 2的购物车体验]]> https://www.360magento.com/blog/magento2-engaging-shopping-cart/ 1. 显示清晰的购物车总览

    确保购物车页面显示清晰而详细的购物车总览信息,包括产品名称、数量、价格和小计。这有助于用户一目了然地了解其购物车内的商品。

    2. 提供即时更新

    通过使用Ajax技术,实现购物车页面的即时更新。当用户更改产品数量或删除产品时,购物车总览应立即反映这些变化,而无需刷新整个页面。

    3. 强调优惠和促销信息

    如果有适用的优惠券或促销活动,确保这些信息在购物车页面中得到明显的展示。这可以激励用户继续购物,并提高购物车价值。

    4. 提供购物车内商品推荐

    在购物车页面底部或侧边,显示购物车内商品的相关推荐。这有助于引导用户发现其他可能感兴趣的产品,增加交叉销售机会。

    5. 实现购物车内编辑功能

    允许用户在购物车内直接编辑产品的数量、修改选项或移除商品。提供清晰的编辑界面,确保用户能够轻松进行调整。

    6. 购物车响应式设计

    确保购物车页面在各种设备上都能够呈现出色。购物车的响应式设计应适应不同屏幕尺寸,提供一致的用户体验。

    7. 引导用户进入结算流程

    在购物车页面明确显示结算按钮,引导用户进入结算流程。提供简化的结算过程,减少步骤,提高用户的购物完成率。

    8. 显示购物车内产品库存状态

    在购物车页面显示产品的实时库存状态,以避免用户在结算时遇到缺货情况。这可以帮助用户做出明智的购物决策。

    9. 提供购物车内产品搜索

    如果购物车中有大量产品,提供购物车内产品搜索功能。这使用户可以快速找到特定的商品,提高购物车内产品的可管理性。

    10. 优化加载速度

    确保购物车页面的加载速度迅速。优化页面元素和资源,减少不必要的HTTP请求,以确保购物车页面在各种网络条件下都能够快速加载。

    ]]>
    Sun, 14 Jan 2024 07:07:41 +0000
    <![CDATA[如何提高Magento2结账流程]]> https://www.360magento.com/blog/magento2-checkout-optimization/ 结账流程是电子商务网站上最关键的一环之一,直接关系到用户是否最终完成购买。在这篇博客文章中,我们将深入探讨如何在Magento 2主题开发中优化结账流程,以提高转化率并提供无缝的购物体验。

    1. 简化结账步骤

    减少结账流程的步骤数量,将多个步骤合并为一个页面或模态框。用户在短时间内完成结账流程,减少因过长流程而放弃购物车的可能性。

    2. 清晰的结账进度指示

    提供清晰的结账进度指示,让用户了解他们在结账流程中的位置。这可以减轻用户焦虑感,增加完成结账的信心。

    3. 提供多种支付选项

    确保结账页面提供多种支付选项,包括信用卡、PayPal、银行转账等。给予用户灵活性,选择他们偏好的支付方式。

    4. 支持快速注册和访客结账

    允许用户使用访客结账或快速注册选项,减少注册流程中的障碍。提供社交媒体登录选项,简化新用户的注册过程。

    5. 自动填充地址和支付信息

    通过使用自动填充技术,预填充用户已保存的地址和支付信息,减少用户在结账过程中输入的工作。这有助于加速结账速度。

    6. 引导用户解决错误

    如果用户在结账过程中遇到错误或遗漏信息,提供明确的错误消息和引导,帮助用户快速解决问题。避免用户因错误而中断结账流程。

    7. 透明的运费和税费信息

    在结账页面清晰显示运费和税费信息,以避免用户在最后一步才发现额外费用。透明的价格信息有助于建立用户的信任感。

    8. 提供订单总览

    在结账页面提供订单总览,包括产品列表、价格明细和总金额。用户应该在确认订单前清晰地了解他们的购买详情。

    9. 实现订单跟踪和通知

    让用户在结账后能够跟踪他们的订单,并通过电子邮件或短信接收订单更新通知。这有助于提供良好的客户服务体验。

    10. 移动设备友好

    确保结账流程在移动设备上能够流畅运行。通过响应式设计和移动优化来提供在小屏幕上的良好用户体验。

    ]]>
    Sun, 14 Jan 2024 03:09:32 +0000
    <![CDATA[Magento 2 主题开发:集成社交媒体分享功能]]> https://www.360magento.com/blog/magento2-social-media-sharing/ 1. 选择社交媒体平台

    在开始之前,确定您想要在网站上集成哪些社交媒体平台的分享功能。常见的选择包括Facebook、Twitter、LinkedIn、Pinterest等。确保选择的平台与您的目标受众和业务目标相匹配。

    2. 获取社交媒体分享按钮代码

    每个社交媒体平台都提供用于在网站上添加分享按钮的官方代码。访问相应的社交媒体开发者页面,获取分享按钮的代码片段。

    3. 创建一个专用的社交媒体分享区域

    在Magento 2主题中,创建一个专用的区域,用于容纳社交媒体分享按钮。通常,这可以在您网站的页脚、顶部导航栏或文章页面的侧边栏中实现。

    4. 将分享按钮代码嵌入主题

    在Magento 2主题的相应文件中,将获取的社交媒体分享按钮代码嵌入到您创建的社交媒体分享区域。这通常涉及到在HTML文件或布局文件中添加相应的代码片段。

    5. 优化分享按钮样式

    确保社交媒体分享按钮与您的网站主题一致,并符合品牌风格。您可以使用CSS样式表对这些按钮进行进一步的样式调整,以使它们看起来更加吸引人。

    /* 示例CSS样式表 */ .social-share-button { margin: 0 10px; font-size: 20px; color: #333; transition: color 0.3s ease-in-out; }
    .social-share-button:hover { color: #007bff; }

    6. 测试社交媒体分享功能

    在完成集成后,通过测试确保社交媒体分享功能在不同浏览器和设备上正常工作。确保分享的内容(例如页面标题、描述)是准确的且可自定义的。

    7. 考虑使用社交媒体插件

    一些社交媒体平台提供插件或API,可以更深度地集成分享功能。考虑使用这些插件,以获得更多定制选项和用户交互功能。

    ]]>
    Sat, 13 Jan 2024 07:05:51 +0000
    <![CDATA[Magento 2 快速搜索功能]]> https://www.360magento.com/blog/magento2-quick-search-enhancement/ 1. 集成Magento 2的内置搜索功能

    Magento 2已经内置了强大的搜索功能,包括全文搜索和自动完成。确保在主题中启用这些功能,并在Magento 2后台配置中进行相应的设置。

    2. 优化搜索建议

    通过在搜索建议中显示产品图像、价格和简短描述等信息,提高用户对搜索结果的了解。这可以通过调整主题的HTML和CSS来实现。

    3. 支持自定义搜索过滤器

    考虑支持自定义搜索过滤器,以便用户可以根据特定条件快速缩小搜索范围。这可以包括按类别、品牌或价格范围过滤搜索结果。

    4. 实施Ajax搜索

    使用Ajax技术实现即时搜索结果的加载,无需刷新整个页面。这样可以提高搜索速度,使用户在输入关键词时立即看到相关结果。

    5. 智能搜索建议

    利用智能搜索建议,根据用户输入的关键词提供相关而准确的建议。可以使用机器学习算法或预测性搜索技术来实现。

    6. 移动设备适配

    确保您的快速搜索功能在移动设备上同样友好。优化搜索建议的显示方式,确保在小屏幕上也能提供良好的用户体验。

    7. 提供搜索历史和热门搜索

    为用户提供搜索历史记录和热门搜索建议,帮助他们更快速地找到他们之前或其他用户常搜索的内容。

    8. 结合自动完成

    将自动完成功能与快速搜索相结合,确保用户在输入过程中能够快速找到他们需要的信息。

    9. 实时搜索反馈

    在进行搜索时,通过实时反馈告知用户搜索的进行状态。这可以包括加载指示器或其他提示,使用户知道系统正在工作。

    ]]>
    Sat, 13 Jan 2024 03:06:56 +0000
    <![CDATA[Magento 2 创建自定义商品详情页模板]]> https://www.360magento.com/blog/magento2-custom-product-details-template/ Magento 2 提供了强大的商品管理系统,但通过创建自定义商品详情页模板,您可以进一步定制和优化商品展示。在这篇博客文章中,我们将深入探讨如何在Magento 2主题开发中创建自定义商品详情页模板,以满足您网站的独特需求。

    1. 了解Magento 2商品详情页结构

    在开始之前,深入了解Magento 2商品详情页的结构是至关重要的。商品详情页通常包括商品图像、价格、描述、属性、加入购物车按钮等元素。了解这些元素的布局和结构是创建自定义模板的第一步。

    2. 创建自定义主题

    确保您已经创建了自定义Magento 2主题。如果没有,请按照Magento 2主题开发的标准流程创建一个新主题,并将其设置为当前主题。

    3. 复制默认商品详情页模板

    在Magento 2主题文件夹中,找到默认商品详情页模板文件,通常位于:

    vendor/magento/module-catalog/view/frontend/templates/product/view/details.phtml

    将该文件复制到您的主题文件夹中,路径可能是:

     
    app/design/frontend/{Vendor}/{Theme}/Magento_Catalog/templates/product/view/details.phtml

    4. 修改自定义模板

    在您复制的details.phtml文件中,您可以根据需要进行修改和定制。您可以添加、删除或调整各个商品详情页元素的排列和样式。

    5. 更新主题布局文件

    在Magento 2主题布局文件中,确保正确引用和加载您创建的自定义商品详情页模板。这通常可以在 catalog_product_view.xml 文件中完成。

    6. 添加自定义样式和脚本

    如果需要添加自定义样式或JavaScript脚本以增强商品详情页的外观和交互性,确保将它们添加到您的主题中的相应文件夹,如:

    app/design/frontend/{Vendor}/{Theme}/web/css/custom-styles.css app/design/frontend/{Vendor}/{Theme}/web/js/custom-scripts.js

    7. 测试和优化

    通过在Magento 2商店中查看商品详情页,测试您的自定义模板。确保它在不同设备和浏览器上都能正常运行,并根据需要进行优化。

    ]]>
    Fri, 12 Jan 2024 07:04:32 +0000
    <![CDATA[Magento2 引入字体和图标]]> https://www.360magento.com/blog/magento2-custom-fonts-icons/ 在Magento 2主题开发中,引入定制字体和图标是提高网站独特性和品牌形象的重要步骤。在这篇博客文章中,我们将深入讨论如何在Magento 2主题中引入和使用定制字体和图标,以打造独特而吸引人的网站设计。

    1. 选择合适的字体

    在选择定制字体之前,考虑您网站的品牌风格和目标受众。您可以选择从Google Fonts、Adobe Fonts等提供商中挑选合适的字体,或者使用自定义字体文件。

    2. 下载和集成字体文件

    一旦选择了字体,下载相应的字体文件(通常包括woff、woff2、ttf等格式)。将这些字体文件添加到Magento 2主题的合适位置,通常是:

     
    app/design/frontend/{Vendor}/{Theme}/web/fonts/

    3. 创建字体样式表

    在Magento 2主题中创建一个新的CSS文件,用于定义您引入的字体样式。确保在样式表中正确设置字体路径:

     
    /* 示例字体样式表 */ @font-face { font-family: 'YourCustomFont'; src: url('../fonts/your-custom-font.woff2') format('woff2'), url('../fonts/your-custom-font.woff') format('woff'); font-weight: normal; font-style: normal; } body { font-family: 'YourCustomFont', sans-serif; }

    4. 引入图标库

    除了字体,图标也是网站设计中的关键元素。您可以选择使用矢量图标库,如Font Awesome或Material Icons。引入图标库的步骤通常包括将样式表和字体文件引入主题中。

    5. 使用CSS样式设置图标

    在Magento 2主题中,通过CSS样式表设置图标的方式类似于字体。创建一个新的CSS文件,定义图标的样式:

     
    /* 示例图标样式表 */ .icon { font-family: 'Font Awesome'; /* 或其他图标库的名称 */ font-weight: normal; font-style: normal; } /* 使用图标 */ .custom-icon::before { content: '\f123'; /* 替换为您所选择图标的Unicode字符 */ }

    6. 更新主题布局

    在Magento 2主题布局文件中,确保正确引用和加载您创建的字体和图标样式表。通常,这可以在 default_head_blocks.xml 文件中完成。

    7. 测试和调整

    在引入定制字体和图标后,通过测试确保它们在不同设备和浏览器上正常显示。根据需要进行调整,以确保字体和图标在整个网站中一致使用。

    ]]>
    Fri, 12 Jan 2024 03:45:28 +0000
    <![CDATA[Magento 2 响应式]]> https://www.360magento.com/blog/magento2-responsive-design/ 随着移动设备的广泛使用,响应式设计在Magento 2主题开发中变得愈发重要。在这篇博客文章中,我们将深入探讨如何在Magento 2主题中实践响应式设计,以确保您的电子商务网站在各种设备上都能提供出色的用户体验。

    1. 了解响应式设计原理

    在开始之前,让我们回顾一下响应式设计的基本原理。响应式设计的目标是使网站布局和内容能够适应不同屏幕尺寸和分辨率,包括桌面、平板和移动设备。

    2. 使用媒体查询(Media Queries)

    Magento 2主题中使用媒体查询是实现响应式设计的关键。通过在CSS中嵌入媒体查询,您可以根据屏幕宽度应用不同的样式,以适应不同设备。

     
    /* 示例媒体查询 */ @media only screen and (max-width: 768px) { /* 在这里添加移动设备的样式 */ } @media only screen and (min-width: 769px) and (max-width: 1024px) { /* 在这里添加平板设备的样式 */ }

    3. 弹性网格布局(Flexible Grid Layout)

    使用弹性网格布局是实现响应式设计的另一个关键因素。确保您的主题使用相对单位(如百分比)而不是固定单位(如像素)来定义网格和元素的宽度,以适应不同屏幕尺寸。

    4. 图像和多媒体的处理

    通过使用max-width属性和height: auto,确保图像在小屏幕上不会溢出。同时,选择适当的图像格式和压缩以提高加载速度。

     
    /* 图像响应式样式 */ img { max-width: 100%; height: auto; }

    5. 移动导航(Mobile Navigation)

    为移动设备设计简洁的导航菜单。您可以考虑使用折叠式菜单、滑动菜单或下拉菜单,以确保在小屏幕上提供更好的导航体验。

    6. 测试在不同设备上

    在开发过程中,定期测试您的Magento 2主题在不同设备上的表现。使用浏览器开发者工具或实际设备进行测试,确保网站在各种情况下都能正常运行。

    ]]>
    Thu, 11 Jan 2024 07:05:19 +0000
    <![CDATA[Magento 2 主题优化]]> https://www.360magento.com/blog/magento2-themes-optimization/ 1. 图片优化

    优化网站图片是提高性能的首要任务。使用压缩工具来减小图片文件大小,同时确保图片质量不受影响。考虑使用WebP格式,以进一步提高加载速度。

    2. 启用Magento 2 缓存

    Magento 2提供了丰富的缓存功能,包括布局缓存、块缓存和页面缓存。确保这些缓存功能都被启用,以减少服务器响应时间并提高整体性能。

    3. 使用CDN(内容分发网络)

    集成内容分发网络(CDN)以加速静态资源的加载速度。CDN会将网站内容分发到全球多个服务器,使用户从最近的服务器获取资源,从而减少加载时间。

    4. Lazy Loading

    实施图片和其他媒体资源的Lazy Loading,以确保仅在用户滚动到可见区域时加载这些资源,而不是一次性加载所有内容。

    5. 压缩CSS和JavaScript

    使用CSS和JavaScript压缩工具来减小文件大小。这有助于减少页面加载时间,尤其是在较慢的网络连接下。

    6. 移除不必要的扩展和模块

    检查并移除不必要的Magento 2扩展和模块,因为它们可能会增加网站的负载时间。只保留对网站功能至关重要的扩展。

    7. 优化数据库

    定期清理Magento 2数据库,删除不需要的数据和日志。您可以使用Magento 2提供的数据库优化工具或使用第三方工具进行优化。

    8. 使用合适的主题

    选择一个轻量且优化良好的Magento 2主题。避免使用过于复杂或过度设计的主题,以确保页面加载速度得到最大程度的优化。

    ]]>
    Thu, 11 Jan 2024 03:25:28 +0000
    <![CDATA[Magento 2主题开发 :创建自定义页面模板]]> https://www.360magento.com/blog/magento2-custom-page-development/ 1. 了解Magento 2页面结构

    在开始之前,让我们先了解Magento 2的页面结构。每个页面通常由多个块(blocks)组成,而这些块又由布局(layouts)控制。了解页面的块和布局结构是创建自定义页面的关键。

    2. 创建自定义主题

    首先,确保您已经创建了自定义Magento 2主题。如果没有,请按照Magento 2主题开发的标准流程创建一个新主题,并将其设置为当前主题。

    3. 创建自定义页面布局

    在主题文件夹中,创建一个新的布局文件,用于定义自定义页面的结构。通常,这个文件可以命名为 cms_custom_page.xml,放置在以下路径:

    app/design/frontend/{Vendor}/{Theme}/Magento_Theme/layout/

    在这个文件中,您可以使用布局标记定义块和容器,以构建您页面的基本结构。

    4. 创建自定义块

    在主题文件夹中,创建一个新的块文件,用于处理页面的业务逻辑和渲染。这个文件可以命名为 CustomPage.php,放置在以下路径:

    app/design/frontend/{Vendor}/{Theme}/Magento_Theme/Block/

    在块文件中,您可以编写PHP代码来处理数据和业务逻辑,并为页面渲染准备必要的信息。

    5. 创建自定义页面模板

    最后,在主题文件夹中,创建一个新的模板文件,用于定义页面的HTML结构。这个文件可以命名为 custom_page.phtml,放置在以下路径:

    app/design/frontend/{Vendor}/{Theme}/Magento_Theme/templates/

    在模板文件中,您可以使用HTML和Magento的块标记(如 <?= $block->getChildHtml('custom.block') ?>)来渲染页面的内容。

    6. 集成到Magento 2系统

    最后一步是将您的自定义页面集成到Magento 2系统中。您可以通过创建一个CMS页面或自定义布局来调用您创建的页面模板。

    ]]>
    Wed, 10 Jan 2024 06:55:39 +0000
    <![CDATA[Magento 2 定制产品列表页]]> https://www.360magento.com/blog/magento2-custom-product-list-page/ 1. 了解Magento 2产品列表结构
    在开始之前,我们需要了解Magento 2产品列表页的结构。产品列表页通常由多个块(blocks)组成,包括产品列表、分页、排序和过滤器等。深入理解这些组件是定制产品列表的关键。

    2. 创建自定义主题
    确保您已经创建了自定义Magento 2主题。如果没有,请按照Magento 2主题开发的标准流程创建一个新主题,并将其设置为当前主题。

    3. 定制产品列表布局
    在主题文件夹中,创建一个新的布局文件,用于定义产品列表页的结构。此文件通常命名为 catalog_product_view.xml,放置在以下路径:

    app/design/frontend/{Vendor}/{Theme}/Magento_Catalog/layout/
    在这个文件中,您可以使用Magento的布局标记定义产品列表块、分页和其他相关组件。

    4. 创建自定义块和模板
    在主题文件夹中,创建一个新的块文件和模板文件,用于处理产品列表的业务逻辑和渲染。块文件通常命名为 ProductList.php,放置在以下路径:


    app/design/frontend/{Vendor}/{Theme}/Magento_Catalog/Block/Product/
    模板文件通常命名为 product_list.phtml,放置在以下路径:


    app/design/frontend/{Vendor}/{Theme}/Magento_Catalog/templates/product/
    在这两个文件中,您可以编写PHP代码和HTML代码,以自定义产品列表的外观和功能。

    5. 集成到Magento 2系统
    最后一步是将您的自定义产品列表集成到Magento 2系统中。您可以通过在CMS页面或自定义布局中调用您创建的产品列表块来实现。

    6. 添加自定义样式和交互效果
    通过使用Less或Sass等CSS预处理器,以及Magento提供的JavaScript库,为您的产品列表添加自定义样式和交互效果。确保您的样式与整体网站设计一致。

    ]]>
    Wed, 10 Jan 2024 03:35:28 +0000
    <![CDATA[Magento2 主题开发]]> https://www.360magento.com/blog/magento2-frontend-development/ Magento 2 是一款强大而灵活的电子商务平台,提供了丰富的功能和扩展性。在这篇博客文章中,我们将深入了解Magento 2前端开发,着重介绍如何构建一个响应式主题,以确保您的电子商务网站在各种设备上都能提供出色的用户体验。

    1. 了解Magento 2主题结构

    在开始之前,让我们首先了解Magento 2主题的基本结构。Magento 2主题通常包含以下几个关键文件夹:

    • app/design/frontend/{Vendor}/{Theme}/:主题文件夹
    • web/:包含CSS、JavaScript和图像等资源
    • Magento_Theme:主题配置文件夹

    2. 创建自定义主题

    要创建自定义主题,您需要在Magento 2的主题文件夹中新建一个文件夹,其中包括主题的名称和供应商名称。例如:

    app/design/frontend/{Vendor}/{Theme}/

    3. 设定主题的基本配置

    在主题文件夹中,您需要创建一个 theme.xml 文件以配置主题的基本信息,如名称、父主题等。此文件通常位于:

    app/design/frontend/{Vendor}/{Theme}/Magento_Theme/

    4. 创建响应式布局

    Magento 2鼓励使用CSS框架和技术来实现响应式设计。您可以使用Less或Sass等预处理器,确保您的CSS代码更加模块化和易于维护。同时,了解Magento 2提供的媒体查询和布局工具,以确保您的主题在各种屏幕尺寸上都能正常显示。

    5. 优化图片和字体

    在响应式主题中,图片和字体的优化至关重要。使用适当的图片压缩工具,并确保字体在不同设备上显示良好。考虑使用WebP格式的图片以提高性能。

    6. 集成JavaScript和Ajax

    Magento 2支持JavaScript的模块化开发,您可以使用RequireJS来管理JavaScript文件的依赖关系。利用Magento提供的Ajax功能,提高网站的交互性和用户体验。

    ]]>
    Tue, 09 Jan 2024 07:54:21 +0000
    <![CDATA[magento2 PHTML小技巧]]> https://www.360magento.com/blog/magento-phtml-tips/ 可翻译的文本
    <?= __('String to translate'); ?>
    

    在.phtml模板中调用静态块ID(如果存在/启用/不为空)

    <?php if($this->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId('BLOCK_ID')->toHtml() != ''): ?>
        <div class="static-block">
            <?php echo $this->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId('BLOCK_ID')->toHtml(); ?>
        </div>
    <?php endif; ?>
    

    在.phtml模板中调用小部件

    <?= $this->getLayout()->createBlock("Magento\Catalog\Block\Product\Widget\NewWidget")
                ->setDisplayType("all_products")
                ->setShowPager(1)
                ->setProductsPerPage(5)
                ->setProductsCount(10)
                ->setPageVarName("pwkvbl")
                ->setTemplate("product/widget/new/content/new_grid.phtml")
                ->toHtml(); ?>
    

    从模块助手调用方法

    <?php $helper = $this->helper('Vendor\Module\Helper\Data'); ?>
    <?php $helper->callMethodName(); ?>
    

    从phtml中的/etc/view.xml获取VAR值

    <?= $block->getVar("gallery/width", 'Magento_Catalog'); ?>
    <?= $block->getVar("breakpoints/mobile/conditions/max-width", 'Magento_Catalog'); ?>
    

    有用的块功能

    $block->getViewFileUrl('images/loader-1.gif'); - from web/images directory
    $block->getViewFileUrl('Magento_Catalog::images/filename.jpg'); - from e.g Magento_Catalog/web/images directory
    
    $block->getUrl('checkout/cart/index');
    $block->getUrl('', array('_direct'=>'hairproducts.html'));
    $block->getUrl('', array('_direct'=>'hairproducts.html', '_query'=>'manufacturer=412'));
    
    $block->getBaseUrl();
    $block->getMediaDirectory();
    $block->getChildBlock('block.name');
    $block->getChildHtml('block.name');
    $block->getChildChildHtml('block.name');
    $block->getBlockHtml('block.name');
    $block->escapeHtml();
    $block->escapeUrl();
    $block->stripTags(); // removes HTML tags
    
    $block->escapeHtml('value', $allowedTags);
    $block->escapeHtmlAttr('value', $escapeSingleQuote);
    $block->escapeJs('value');
    $block->escapeUrl($url);
    

    产品属性操作示例

    <?php if($_product->getTypeId() == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE): ?>
            <?php
            $deliveryTime = $_product->getResource()->getAttribute('delivery_time');
            $minDeliveryTime = $deliveryTime->getFrontend()->getValue($_product);
            ?>
            <div class="delivery-time">
                <?php echo __('Delivery time: %1', $minDeliveryTime); ?>
            </div>
    <?php endif; ?>
    
    $product->getAttributeText('color'); - value as 'text' label
    $product->getResource()->getAttribute('color')->getFrontend()->getValue($product); - value as 'text' label
    $product->getData('color'); - value as 'id attribute number'
    

    在类别视图中显示样本后执行 JavaScript 代码

    <script>
        require(['jquery', 'Magento_Swatches/js/swatch-renderer'], function ($, swatch) {
            $(document).on('swatch.initialized', function() {
                // Here make some layout changes
            });
        });
    </script>  
    

    可用于在调试时获取句柄列表

    $this->getLayout()->getUpdate()->getHandles();
    

    获取后端配置选项启用/禁用

    <?php $config = $block->getLayout()->createBlock(\Magento\Config\Block\System\Config\Form::class);?>
    <?php if($config->getConfigValue('dev/translate_inline/active')): ?>
      // do something
    <?php endif; ?>
    

    JavaScript 中的媒体查询

    <script type="text/javascript">
            require(['jquery', 'matchMedia'], function ($, mediaCheck) {
                mediaCheck({
                    media: '(min-width: 768px)',
                    // Switch to Desktop Version
                    entry: function () {
                       alert('desktop');
                    },
                    // Switch to Mobile Version
                    exit: function () {
                        alert('mobile');
                    }
                });
            });
        </script>
    

    调用 Fotorama 图库脚本的 2 种方法

    <script type="text/x-magento-init">
        {
            "[data-gallery-role=gallery-placeholder]": {
                "mage/gallery/gallery": {
                    "mixins":["magnifier/magnify"],
                    "magnifierOpts": <?= $block->getMagnifier() ?>,
                    "data": <?= $block->getGalleryImagesJson() ?>,
                    "options": <?= $block->getGalleryOptions()->getOptionsJson() ?>,
                    "fullscreen": <?= $block->getGalleryOptions()->getFSOptionsJson() ?>,
                    "breakpoints": <?= $block->getBreakpoints() ?>
                }
            }
        }
    </script>
    
    <script>
        require(['jquery', 'mage/gallery/gallery'], function ($, gallery) {
            $(function () {
                $('[data-gallery-role="gallery-placeholder"]').each(function(index, element) {
                    gallery({
                        "mixins":["magnifier/magnify"],
                        "magnifierOpts": <?= $block->getMagnifier() ?>,
                        "data": <?= $block->getGalleryImagesJson() ?>,
                        "options": <?= $block->getGalleryOptions()->getOptionsJson() ?>,
                        "fullscreen": <?= $block->getGalleryOptions()->getFSOptionsJson() ?>,
                        "breakpoints": <?= $block->getBreakpoints() ?>
                    }, element);
                 });
            });
        });
    </script>
    

    脚本初始化

    标准

    <div class="swiper-container header-slider" data-mage-init='{"Swissup_Swiper/js/swiper": {"loop":true,"centeredSlides":true,"autoplay": {"delay": 10000}, "navigation":{"nextEl":".swiper-button-next","prevEl":".swiper-button-prev"}}}'>
        <div class="swiper-wrapper">
            <div class="swiper-slide">1</div>
            <div class="swiper-slide">2</div>
            <div class="swiper-slide">3</div>
       </div>
    </div>
    

    或更好:

    <script type="text/lazy">
        require(['jquery', 'Swissup_Swiper/js/swiper'], function ($, swiper) {
            $(function() {
                $('.header-slider').each(function(index, element) {
                    swiper({"loop":true,"centeredSlides":true,"autoplay": {"delay": 10000}, "navigation":{"nextEl":".swiper-button-next","prevEl":".swiper-button-prev"}}, element);
                 });
            });
        });
    </script>
    ]]>
    Mon, 08 Jan 2024 16:02:33 +0000
    <![CDATA[Magento2 常用变量]]> https://www.360magento.com/blog/magento-curly-braces-variable/ 自定义变量

    商店网址

    https://www.360magento.com/customer/account/- 末尾有斜线

    https://www.360magento.com/contact-us- 末尾没有斜杠

    媒体网址

    https://www.360magento.com/media/wysiwyg/your-image.jpg {{view url='images/logo.svg'}} {{view url='Magento_Theme::images/logo.svg'}}

    区块ID

    小部件

    新产品

    存储联系信息变量

    基本安全 URL https://www.360magento.com/

    一般联系电子邮件 sales@360magento.com

    新帐户模板变量

    客户帐户网址{{var this.getUrl($store, ‘customer/account/’)}}

    客户邮箱{{var customer.email}}

    新订单模板变量

    订单号{{var order.increment_id}}

    付款详情{{var payment_html|raw}}

    运输说明{{var order.getShippingDescription()}}

    电子邮件模板变量

    电子邮件徽标图像 URL{{var logo_url}}

    电子邮件徽标图像宽度{{var logo_width}}

    – For registration:
    {{var customer}}
    
    {{var customer.ID}}
    
    {{var customer.email}}
    
    {{var customer.firstname}}
    
    {{var customer.lastname}}
    
    {{var customer.name}}
    
    {{var customer.password}}
    
    {{var customer.created_in}} Store Name
    
    {{var customer.dob}} Date of Birth
    
    {{var customer.password_hash}}
    
    {{var customer.prefix}}
    
    {{var customer.middlename}} Initial
    
    {{var customer.suffix}}
    
    {{var customer.group_id}}
    
    {{var customer.taxvat}}
    
    {{var customer.store.name}}
    
    {{var customer.store.group.name}}
    
    – To subscribe/unsubscribe newsletter:
    
    {{var subscriber.getConfirmationLink()}}
    
    {{var subscriber.getUnsubscriptionLink()}}
    
    {{var subscriber.email}}
    
    – Send to a friend:
    
    {{var product_image}}
    
    {{var name}} Recipient’s Name
    
    {{var email}} Recipient’s Email
    
    {{var product_name}} Product Name
    
    {{var product_url}} Product Url
    
    {{var message}} Message Text
    
    {{var sender_name}} Sender’s Name
    
    {{var sender_email}} Sender’s Email
    
    {{var product_image}} Product Image
    
    – Depend Condition
    
    {{depend order.getIsNotVirtual()}}
    
    {{/depend}}
    
    {{depend salable}}
    
    {{/depend}}
    
    – If Condition
    
    {{if order.getIsNotVirtual()}}
    
    {{else}}
    
    {{/if}}
    
    (else is optional)
    
    
    – New order : Shipping Address
    
    {{var order.getShippingAddress().format(‘html’)}}
    
    Items of the shipping address :
    
    {{var order.getShippingAddress().getName()}} Get the first and last name
    
    {{var order.getShippingAddress().getPrefix()}}
    
    {{var order.getShippingAddress().getFirstName()}}
    
    {{var order.getShippingAddress().getMiddleName()}}
    
    {{var order.getShippingAddress().getLastName()}}
    
    {{var order.getShippingAddress().getSuffix()}}
    
    {{var order.getShippingAddress().getStreet1()}}
    
    {{var order.getShippingAddress().getStreet2()}}
    
    {{var order.getShippingAddress().getCity()}}
    
    {{var order.getShippingAddress().getRegion()}}
    
    {{var order.getShippingAddress().getPostcode()}}
    
    {{var order.getShippingAddress().getCountry()}} Get the country’s ID
    
    {{var order.getShippingAddress().getCountryModel().getName()}} Get the country’s full name
    
    {{var order.getShippingAddress().getRegion()}}
    
    {{var order.getShippingAddress().getTelephone()}}
    
    – Other
    
    {{var addAllLink}}
    
    {{var alertGrid}}
    
    {{var billingAddress.format(‘html’)}}
    
    {{var checkoutType}}
    
    {{var comment}}
    
    {{var creditmemo.id}}
    
    {{var creditmemo.increment_id}}
    
    {{var data.comment}}
    
    {{var data.email}}
    
    {{var data.name}}
    
    {{var data.telephone}}
    
    {{var dateAndTime}}
    
    {{var invoice.id}}
    
    {{var invoice.increment_id}}
    
    {{var invoice.created_at}}
    
    {{var items}}
    
    {{var items_html}}
    
    {{var message}}
    
    {{var name}}
    
    {{var order.customer_email}}
    
    {{var order.getBillingAddress().format(‘html’)}}
    
    {{var order.getBillingAddress().getName()}}
    
    {{var order.getCreatedAtFormated(‘long’)}}
    
    {{var order.getCustomerName()}}
    
    {{var order.getCustomerFirstname()}}
    
    {{var order.getCustomerLastname()}}
    
    {{var order.getEmailCustomerNote()}} Currently unknwon how to test this variable for being set/empty
    
    {{var order.getShippingDescription()}}
    
    {{var order.getStatusLabel()}}
    
    {{var order.getStoreGroupName()}}
    
    {{var order.id}}
    
    {{var order.increment_id}}
    
    {{var password}}
    
    {{var payment_html}}
    
    {{var paymentMethod}}
    
    {{var product_name}}
    
    {{var product_url}}
    
    {{var reason}} Reason for payment failure
    
    {{var shipment.increment_id}}
    
    {{var shippingAddress.format(‘html’)}}
    
    {{var shippingMethod}}
    
    {{var total}}
    
    {{var user.name}}
    
    {{var viewOnSiteLink}}
    
    {{var warnings}}
    
    {{var billing.name}}
    ]]>
    Mon, 08 Jan 2024 07:58:44 +0000
    <![CDATA[有用的 Magento 2 CLI 命令]]> https://www.360magento.com/blog/magento2-CLI-commands/ 有用的 Magento 2 CLI 命令

    部署模式功能:

    php bin/magento deploy:mode:show
    php bin/magento deploy:mode:set developer ( default | production | developer )
    php bin/magento deploy:mode:set production --skip-compilation
    
    php bin/magento maintenance:disable
    php bin/magento maintenance:enable
    php bin/magento maintenance:enable --ip=192.0.0.1 --ip=192.0.0.2 (for all clients except this IPs)
    php bin/magento maintenance:enable --ip=none (to clear the list of IPs)
    

    用于开发的 CSS 和 JS 配置

    php bin/magento config:set dev/js/enable_js_bundling 0
    php bin/magento config:set dev/js/merge_files 0
    php bin/magento config:set dev/js/minify_files 0
    php bin/magento config:set dev/css/merge_css_files 0
    php bin/magento config:set dev/css/minify_files 0
    php bin/magento config:set dev/static/sign 0
    
    php bin/magento config:set --scope="stores" --scope-code="default" dev/js/minify_files 0
    

    缓存操作:

    php bin/magento cache:status
    php bin/magento c:f ( cache:flush }
    php bin/magento c:c ( cache:clean }
    php bin/magento cache:disable full_page layout block_html translate
    

    默认缓存类型:

     config
     layout
     block_html
     collections
     reflection
     db_ddl
     compiled_config
     eav
     customer_notification
     config_integration
     config_integration_api
     full_page
     config_webservice
     translate
     vertex
    

    模块操作(检查当前状态/禁用模块/启用模块):

    php bin/magento module:status
    php bin/magento module:disable VENDOR_MODULENAME
    php bin/magento module:enable VENDOR_MODULENAME
    php bin/magento module:uninstall VENDOR_MODULENAME (if installed by Composer)
    

    设置升级/设置编译/静态内容部署:

    php -d memory_limit=2048M bin/magento setup:upgrade
    php -d memory_limit=2048M bin/magento setup:di:compile
    php -d memory_limit=2048M bin/magento setup:static-content:deploy
    php bin/magento setup:static-content:deploy pl_PL -f
    php bin/magento setup:static-content:deploy pl_PL --theme Vendor/theme --no-html-minify -f
    php bin/magento setup:static-content:deploy pl_PL en_US en_GB --jobs 20
    
    

    设置配置:

    php bin/magento setup:store-config:set --base-url="http://project.dev/"
    php bin/magento setup:store-config:set --base-url-secure="https://project.dev/"
    
    php bin/magento config:set admin/security/session_lifetime 604800 ( 86400 = 1 day / 604800 = 7 days / 31536000 = 1 year / etc )
    php bin/magento config:set admin/security/password_is_forced 0
    

    索引器(重新索引|重置):

    php bin/magento indexer:reset
    php -d memory_limit=2048M bin/magento indexer:reindex
    
    php bin/magento indexer:status
    php bin/magento indexer:reset cataloginventory_stock
    php bin/magento indexer:reindex cataloginventory_stock
    

    为特定模块生成翻译包

    php bin/magento i18n:collect-phrases -o app/code/Module/Vendor/i18n/pl_PL.csv app/code/Module/Vendor/
    php bin/magento i18n:collect-phrases --output="app/design/frontend//Module/Vendor/i18n/pl_PL.csv" --magento (This option adds themes or modules to each line in the dictionary.)
    

    目录图像调整大小:

    php bin/magento catalog:image:resize
    

    对于管理员

    php bin/magento admin:user:create
    php bin/magento info:adminuri
    php bin/magento admin:user:unlock USERNAME
    

    获取所有可用命令的列表

    php bin/magento list
    php bin/magento help
    ]]>
    Mon, 08 Jan 2024 03:56:35 +0000
    <![CDATA[Magento2 XML中的属性说明]]> https://www.360magento.com/blog/magento2-handy-snippets/ 带模板的自定义块
    <block class="Magento\Framework\View\Element\Template" name="my_block" template="Vendor_Module::my-template.phtml" /> ( after="-" or before="-" )
    <block class="Magento\Framework\View\Element\Template" name="footer_logo_brands" template="Magento_Theme::html/brand-logos.phtml" after="footer_links"/> 
    

    具有配置条件的块

    <block class="Magento\Newsletter\Block\Subscribe" name="form.subscribe" as="subscribe" before="-" template="Magento_Newsletter::subscribe.phtml" ifconfig="newsletter/general/active"/>
    

    容器内的块

    <container name="some.block.wrapper" htmlTag="div" htmlClass="container">
          // block here
    </container>

    从 XML 调用静态块

    <referenceContainer name="footer-container">
                <block class="Magento\Cms\Block\Block" name="promo" before="-">
                    <arguments>
                        <argument name="block_id" xsi:type="string">promo</argument>
                    </arguments>
                </block>
    </referenceContainer>
    

    在xml中设置模板的两种方法

    <referenceBlock name="page.main.title" template="Vendor_Module::path/to/template.phtml"/>`
    
    <referenceBlock name="page.main.title">
    	<arguments>
    		<argument name="template" xsi:type="string">Vendor_Module::path/to/template.phtml</argument>
    	</arguments>
    </referenceBlock>
    

    在xml中设置模板布局(例如catalog_category_view.xml中的“2columns-left”)

    <?xml version="1.0"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            ...
        </body>
    </page>
    

    将自定义链接添加到top.links(客户下拉列表)

    <referenceBlock name="top.links">
        <block class="Magento\Framework\View\Element\Html\Link" name="acount-create-link">
            <arguments>
                <argument name="label" xsi:type="string" translate="true">Create an Account</argument>
                <argument name="path" xsi:type="string">customer/account/create</argument>
                <argument name="sortOrder" xsi:type="number">100</argument>
            </arguments>
        </block>
    </referenceBlock>
    

    包括静态资源(JavaScript、CSS、字体)

    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
      <head>
        <!-- Add local styles resources -->
        <css src="css/my-styles.css" />
        <css src="<Namespace>_<Module>::css/custom-styles.css" />
    
        <!-- The following two ways to add local JavaScript files are equal -->
        <script src="Magento_Catalog::js/sample1.js" />
        <script src="Magento_Catalog/js/sample1.js" />
    
        <!-- Magento support async or defer attribute in script tag -->
        <script async="" src="Magento_Catalog::js/sample1.js" />
        <script defer="" src="Magento_Catalog::js/sample1.js" />
    
        <link src="js/sample.js" />
        <link src="sample.js" />
    
        <!-- Add external resources -->
        <css src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css" src_type="url" />
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js" src_type="url" />
        <link rel="stylesheet" type="text/css" src="http://fonts.googleapis.com/css?family=Montserrat" src_type="url" />
      </head>
    </page>
    

    删除静态资源(JavaScript、CSS、字体)

    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
       <head>
        <!-- Remove local styles resources -->
        <remove src="css/styles-m.css" />
        <remove src="<Namespace>_<ModuleName>::css/styles.css" />
    
        <!-- Remove js resources -->
        <remove src="my-js.js" />
        <remove src="Magento_Catalog::js/sample1.js" />
    
        <!-- Remove external resources -->
        <remove src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css" />
        <remove src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js" />
        <remove src="http://fonts.googleapis.com/css?family=Montserrat" />
       </head>
    </page>
    

    将元标记添加到头块

    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
       <head>
        <!-- This will create a tag like '<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">' -->
        <meta name="x_ua_compatible" content="IE=edge,chrome=1"/>
        <!-- This will create a tag like '<meta property="og:type" content="article"/>'' -->
        <meta name="og:type" content="article"/>
        <!-- This will create a tag like '<meta charset="UTF-8">' -->
        <meta name="charset" content="UTF-8"/>
        <!-- This will create a tag like '<meta http-equiv="Content-Type" content="content-type-value"/>' -->
        <meta name="content_type" content="content-type-value"/>
        <!-- This tag will not render (see \Magento\Framework\View\Page\Config\Renderer for details) -->
        <meta name="media_type" content="any-value"/>
        <!-- This will create a tag like '<meta name="my_custom_type" content="my_custom_value"/>' -->
        <meta name="my_custom_type" content="my_custom_value"/>
       </head>
    </page>
    

    设置身体属性

    <body>
         <attribute name="class" value="my-new-body-class"/>
    </body>
    

    设置自定义页面标题

    <referenceBlock name="page.main.title">
         <action method="setPageTitle">
              <argument translate="true" name="title" xsi:type="string">My title</argument>
         </action>
    </referenceBlock>
    ]]>
    Sun, 07 Jan 2024 07:49:31 +0000
    <![CDATA[Magento网站管理步骤]]> https://www.360magento.com/blog/magento-website-management/ Magento是一款功能强大的电子商务平台,为在线商家提供了一个完整的解决方案。然而,要确保您的Magento网站能够取得成功并实现预期的业绩,良好的网站管理是至关重要的。本文将介绍一些关键的Magento网站管理步骤,以帮助您优化网站性能、提升用户体验并实现业务目标。

    1. 定期备份和恢复:
      每个Magento网站都应该定期备份其数据库和文件,以防止数据丢失或网站故障。您可以使用Magento的内置备份工具或第三方插件来执行自动备份,并确保备份文件的安全存储。在需要时,您可以使用这些备份文件来快速恢复网站。

    2. 更新和维护Magento版本:
      Magento定期发布更新和修复程序,以解决安全漏洞和错误。确保您的Magento网站始终运行最新版本是至关重要的,这将有助于保护您的网站免受潜在的安全威胁,并提供更好的性能和功能。在进行任何升级前,务必在测试环境中进行充分的测试和验证。

    3. 密码和访问控制:
      确保您的Magento网站具有强大的管理员密码,并将其保持机密。此外,限制对Magento后台的访问,并为每个管理员分配适当的权限。这样可以减少潜在的安全风险,并防止未经授权的访问和操作。

    4. 监控和性能优化:
      使用监控工具来实时监测您的Magento网站的性能和可用性。这些工具可以提供关键指标,如网站的加载时间、访问量和服务器资源使用情况。通过定期监控,您可以及时发现并解决潜在的性能问题,并确保您的网站始终处于最佳状态。

    5. 安全和防护措施:
      采取适当的安全措施来保护您的Magento网站免受潜在的攻击和恶意行为。这包括安装SSL证书,以确保安全的数据传输,以及配置防火墙和入侵检测系统来阻止恶意流量和未经授权的访问。

    6. 更新和优化内容:
      定期更新您的Magento网站上的内容,并进行关键字优化,以提高搜索引擎排名和流量。确保您的商品信息、价格、促销和页面内容都是准确、清晰和吸引人的。此外,确保您的网站页面加载速度快,并具有良好的用户导航和响应式设计。

    7. 用户支持和反馈:
      提供优质的用户支持,并鼓励用户提供反馈和建议。确保您的Magento网站上有易于找到的联系方式,并及时回复用户的问题和需求。用户反馈是改进您的网站和提供更好用户体验的重要来源。

    ]]>
    Sun, 07 Jan 2024 03:46:09 +0000
    <![CDATA[Magento 2的性能优化]]> https://www.360magento.com/blog/Magento2-asa-srapageppasa/ Magento 2是一款功能强大的电子商务平台,但在处理大量产品和访问量较高的情况下,性能可能受到影响。本文将介绍一些Magento 2性能优化的关键方面和最佳实践,帮助您加速您的电子商务网站。

    1. 了解Magento 2的性能挑战:

      • Magento 2的复杂性和资源需求
      • 响应时间和页面加载速度的重要性
      • 常见的性能瓶颈和挑战
    2. 优化Magento 2的服务器环境:

      • 选择适当的服务器规格和配置
      • 配置服务器缓存和加速器
      • 优化数据库性能和查询
    3. Magento 2缓存管理和优化:

      • 启用和配置Magento 2的缓存
      • 优化缓存存储和清除策略
      • 利用Varnish和Redis等外部缓存解决方案
    4. 图像和静态资源优化:

      • 优化图像大小和格式
      • 使用图像CDN加速图像加载
      • 压缩和合并CSS和JavaScript文件
    5. 代码和数据库优化:

      • 优化Magento 2的代码和扩展
      • 避免不必要的重写和扩展
      • 优化数据库查询和索引
    6. 性能监测和测试:

      • 使用Magento 2的性能工具和插件
      • 进行负载测试和压力测试
      • 分析和监控网站性能
    7. 高可用性和容错性:

      • 设置Magento 2的备份和恢复策略
      • 实施负载均衡和故障转移机制
      • 备份和优化Magento 2的数据
    ]]>
    Sat, 06 Jan 2024 07:43:19 +0000
    <![CDATA[Magento 2的主题定制]]> https://www.360magento.com/blog/magento2-theme-customization/ Magento 2是一款强大的电子商务平台,提供了丰富的主题定制功能,使您能够创建独特而引人注目的在线商店外观。本文将介绍Magento 2主题定制的基本概念和步骤,以及如何利用它来实现个性化的品牌形象。

    1. Magento 2主题定制的基础知识:

      • Magento 2的主题结构和层次
      • 主题文件和目录的作用
      • 主题继承和覆盖机制
    2. 创建自定义Magento 2主题:

      • 创建主题文件和目录结构
      • 定义主题的基本配置
      • 创建和修改布局文件
      • 自定义样式和CSS
      • 添加和修改静态资源(图像、字体等)
    3. 主题定制的最佳实践:

      • 使用子主题进行定制
      • 利用Magento 2的主题继承机制
      • 重写和扩展Magento 2的模板文件
      • 利用Magento 2的UI组件进行布局定制
    4. 主题定制的高级技巧和扩展:

      • 利用Magento 2的LESS和RequireJS进行高级样式和脚本定制
      • 创建自定义模块和主题集成
      • 主题本地化和多语言支持
    5. 主题定制的测试和部署:

      • 使用Magento 2的开发者工具进行主题定制的调试和测试
      • 主题定制的部署和发布流程
      • 主题定制的性能优化和缓存管理
    ]]>
    Sat, 06 Jan 2024 03:41:37 +0000
    <![CDATA[了解Magento 2:功能强大的电子商务平台]]> https://www.360magento.com/blog/introduction-to-magento2/ Magento 2是一款开源的电子商务平台,具有丰富的功能和灵活的可扩展性。本文将介绍Magento 2的主要特点和功能,以及为什么它是构建强大在线商店的理想选择。

    1. Magento 2的特点和优势:

      • 现代化的架构和技术栈
      • 强大的扩展性和定制性
      • 多店铺和多语言支持
      • 响应式设计和移动优化
      • 内置的SEO功能和营销工具
    2. Magento 2的核心功能:

      • 产品和目录管理
      • 订单和支付处理
      • 客户管理和个性化体验
      • 营销和促销工具
      • 物流和库存管理
    3. Magento 2的模块和扩展市场:

      • Magento Marketplace的扩展和主题
      • 自定义模块和主题开发
      • 第三方集成和API支持
    4. Magento 2的性能和安全性:

      • 缓存和索引优化
      • 代码和数据的安全性
      • 支持HTTPS和PCI DSS合规性
    5. Magento 2的社区和支持:

      • Magento开发者社区和论坛
      • 官方文档和教程资源
      • Magento认证和培训机会

    结论:Magento 2是一款功能强大的电子商务平台,它提供了丰富的功能和灵活的可扩展性,让您能够构建和管理强大的在线商店。无论是小型企业还是大型企业,Magento 2都是一个值得考虑的选择。

    ]]>
    Fri, 05 Jan 2024 08:39:35 +0000
    <![CDATA[Magento的API来获取产品信息]]> https://www.360magento.com/blog/magento2-api-get-products/ $host = 'http://your-magento-site.com'; $apiUser = 'your_api_username'; $apiKey = 'your_api_key'; $productId = 123; // 产品ID $client = new SoapClient($host . '/api/soap/?wsdl'); // 登录到API $session = $client->login($apiUser, $apiKey); // 获取产品信息 $productInfo = $client->call($session, 'catalog_product.info', $productId); // 打印产品信息 echo '产品名称:' . $productInfo['name'] . "\n"; echo '产品价格:' . $productInfo['price'] . "\n"; echo '产品描述:' . $productInfo['description'] . "\n"; // 注销API会话 $client->endSession($session);


    在上述示例代码中,您需要替换以下变量:

    • $host:您的Magento站点的URL。
    • $apiUser:您在Magento中创建的API用户名。
    • $apiKey:与API用户关联的API密钥。
    • $productId:您要获取信息的产品ID。

    上述代码首先创建了一个SOAP客户端,并使用提供的URL进行登录。然后,通过调用catalog_product.info方法并传递产品ID,从API中获取产品信息。最后,通过打印结果来显示产品的名称、价格和描述等信息。

    请确保您的Magento站点已启用并配置了SOAP API,并且您已经具有正确的API访问凭据。

    ]]>
    Thu, 04 Jan 2024 16:33:03 +0000
    <![CDATA[如何配置 Magento 2 管理操作日志]]> https://www.360magento.com/blog/system_config_edit/ Magento 2是一款强大的电商平台,为了确保系统的安全性和稳定性,配置管理操作日志是至关重要的。管理操作日志记录了后台用户的活动,帮助你跟踪变更、排除问题,并提高系统监控水平。

    以下是配置Magento 2管理操作日志的步骤:

    步骤1:登录Magento 2后台

    首先,使用管理员凭证登录Magento 2后台。

    步骤2:打开配置设置

    1. 在左侧导航栏中,选择“系统”。
    2. 在下拉菜单中,选择“配置”。

    步骤3:选择管理操作日志设置

    在配置页面,选择“高级”部分。在这里,你可以看到“系统”下的“管理操作日志”。

    步骤4:启用管理操作日志

    1. 将“启用管理操作日志”选项切换为“是”。
    2. 根据需要,你还可以调整“最长日志保留期限”以限制日志保存的时间。

    步骤5:保存配置

    确保在更改设置后,点击页面右上角的“保存配置”按钮。

    步骤6:检查日志

    现在,Magento 2将开始记录管理操作日志。你可以在系统的/var/log目录中找到日志文件。

    ]]>
    Thu, 04 Jan 2024 06:52:45 +0000
    <![CDATA[Magento中重写控制器]]> https://www.360magento.com/blog/magento-review-Controller/ 1. 了解Magento的控制器结构

    在开始重写控制器之前,首先需要了解Magento的控制器结构。Magento的控制器通常位于app/code/{Vendor}/{Module}/Controller/{Path}目录下。了解控制器的路径结构以及它们是如何组织的,对于成功地进行重写是至关重要的。

    2. 选择重写的控制器

    确定你想要重写的控制器。在Magento中,你可以通过查看模块的routes.xml文件来了解控制器的路由和名称。选择与你定制需求相关的控制器进行重写。

    3. 创建一个新的模块

    在开始重写之前,创建一个新的Magento模块。这可以通过创建一个registration.php文件和一个module.xml文件来实现。确保在module.xml文件中指定正确的依赖关系和顺序。

    4. 创建新的控制器类

    在新的模块中创建一个新的控制器类,该类将用于替代原始控制器。确保这个类继承自原始控制器,并重写你需要修改的方法。

    5. 配置重写

    在新的模块目录下,创建一个di.xml文件,用于配置控制器的重写。在文件中添加以下内容:

    确保替换大括号内的占位符为你实际的供应商、模块和控制器路径。

    6. 清除缓存

    在完成上述步骤后,清除Magento缓存以确保新的控制器类得到正确加载。

    ]]>
    Wed, 03 Jan 2024 07:14:36 +0000
    <![CDATA[Magento JS异步加载优化]]> https://www.360magento.com/blog/magento-js-custom/ JavaScript异步加载是提高Magento网站性能的一项重要策略。通过在加载JavaScript时优化异步加载,你可以确保页面在等待文件下载和执行时仍能够迅速呈现。以下是一些建议,帮助你优化Magento JS异步加载。

    1. 合理使用异步标记

    在Magento中,你可以使用async标记来异步加载JavaScript文件。确保仅将此标记应用于不影响关键用户交互和页面渲染的文件。对于必需的JS文件,考虑使用延迟加载,以确保它们在页面准备好时加载。

    <script src="your-script.js" async></script>

    2. 考虑使用延迟加载

    延迟加载允许JavaScript文件在页面加载完毕后再加载,而不会阻塞页面的初始渲染。这对于非关键脚本和跟踪代码非常有用,但要小心不要延迟加载对页面关键功能和用户体验有影响的文件。
    <script src="your-script.js" defer></script>

    3. 优化加载顺序

    确保按照正确的顺序加载JavaScript文件,特别是对于依赖关系较强的文件。这可以防止潜在的错误和确保文件按照正确的顺序执行。

    4. 使用外部库和CDN

    考虑将常用的JavaScript库,如jQuery等,从外部引入并托管在内容分发网络(CDN)上。这可以提高文件加载速度,并利用CDN的缓存效果。

    5. 定期检查和测试

    在Magento后台启用JS合并和缓存时,定期检查并测试你的网站性能。确保这些优化措施仍然有效,并根据需要进行调整。

    ]]>
    Wed, 03 Jan 2024 03:11:00 +0000
    <![CDATA[Magento布局]]> https://www.360magento.com/blog/magento2-layout-custom/ Magento是一款强大而灵活的电子商务平台,而布局设计是打造成功在线商店的关键因素之一。在这篇博客中,我们将深入探讨Magento布局的相关概念,帮助你优化你的网站设计,提升用户体验。

    1. Magento布局基础

    Magento采用XML文件定义布局,将页面划分为块(blocks)、容器(containers)和其他元素。了解布局基础是优化和定制你的商店外观的第一步。

    2. 主题和布局

    Magento主题是布局的核心组成部分之一。通过选择或创建适合你品牌的主题,你可以轻松改变整个商店的外观。了解如何在Magento中使用主题以及如何自定义主题布局是成功设计商店的关键。

    3. 响应式设计

    随着移动设备的普及,响应式设计变得至关重要。确保你的Magento布局能够适应不同屏幕大小和设备类型,提供无缝的用户体验。

    4. 布局调试和优化

    在实际设计中,布局可能会遇到一些挑战。学会使用Magento提供的调试工具,如Layout Handles和Template Path Hints,可以帮助你更轻松地识别和解决布局问题。

    5. 自定义布局元素

    除了使用Magento提供的默认布局元素外,你还可以通过自定义块和容器来进一步个性化你的商店。掌握如何添加自定义布局元素将帮助你实现更精确的设计目标。

    ]]>
    Tue, 02 Jan 2024 07:19:24 +0000
    <![CDATA[Magento 2集成支付]]> https://www.360magento.com/blog/integrating-payment-gateways-magento-2/ 在电商网站中,集成支付网关是一个关键的任务,而Magento 2提供了强大的功能来实现与各种支付网关的集成。本篇博客将为您介绍Magento 2集成支付网关的步骤和注意事项,帮助您顺利实现安全、可靠的在线支付功能。

    首先,我们将讨论Magento 2支付网关集成的准备工作。这包括了解您选择的支付网关的要求和接口文档,获取必要的API密钥和凭证,以及确保您的Magento 2网站具备HTTPS支持和SSL证书等安全要求。

    接下来,我们将深入探讨Magento 2支付网关集成的实际步骤。我们将介绍如何使用Magento 2的扩展机制来安装和配置支付网关模块。您将学习如何设置支付网关的参数、回调URL和通知机制,以确保支付交易的正常处理和状态更新。

    我们还将讨论Magento 2中的支付流程和订单管理。您将了解如何处理支付请求、生成订单、更新订单状态和发送支付确认邮件给客户。

    除了基本的支付网关集成,我们还将介绍一些高级功能和注意事项。这包括处理退款和取消订单、处理异常情况和错误处理、以及实施额外的安全性措施,如双因素身份验证和反欺诈策略等。

    最后,我们将分享一些Magento 2支付网关集成的最佳实践。这些实践包括进行充分的测试和模拟交易,定期监测支付交易日志和报告,以及保持与支付网关提供商的沟通和升级。

    ]]>
    Mon, 01 Jan 2024 07:08:27 +0000
    <![CDATA[Magento主题开发]]> https://www.360magento.com/blog/magento-theme-development/ 在电商网站设计中,主题起着至关重要的作用,决定了网站的外观和用户体验。Magento作为一款流行的电商平台,提供了强大而灵活的主题开发功能,使网站开发人员能够根据特定需求定制化网站设计。本文将详细介绍Magento主题开发的关键步骤,帮助您创建独特且符合品牌形象的电商网站。

    1. 理解Magento主题结构

    首先,我们将介绍Magento主题的基本结构。您将了解到Magento主题的目录结构,包括主题文件夹、布局文件、模板文件、静态资源文件等。我们将解释每个文件夹和文件的作用,以及它们在主题开发中的重要性。

    1. 创建自定义主题

    接下来,我们将讨论如何创建自定义主题。您将学习如何在Magento中创建新的主题文件夹,并设置主题的层次结构。我们还将介绍如何创建主题的配置文件,并设置主题的父主题(如果有)。此外,我们将探讨如何在Magento后台中启用和配置自定义主题。

    1. 定义主题布局

    在本节中,我们将重点介绍如何定义主题的布局。您将学习如何创建主题的布局文件,并使用Magento的布局指令来定义页面的结构和内容。我们将讨论如何定义主页、分类页面、产品页面等的布局,并展示如何使用块和容器来组织页面的不同部分。

    1. 定制主题样式

    在此部分,我们将讨论如何定制主题的样式。您将了解如何使用CSS和LESS来修改主题的样式表,并实现自定义的外观效果。我们将介绍如何使用Magento的样式继承机制和样式覆盖规则,以确保样式修改的正确应用。

    1. 集成JavaScript和定制功能

    最后,我们将讨论如何集成JavaScript和定制功能到主题中。您将学习如何添加自定义JavaScript文件,并进行必要的初始化和事件处理。我们还将介绍如何使用Magento的模块开发功能,添加自定义功能和扩展到主题中,以满足特定需求。

    ]]>
    Sun, 31 Dec 2023 16:22:04 +0000
    <![CDATA[Magento 2主题开发]]> https://www.360magento.com/blog/magento-2-theme-development/ Magento 2作为一款功能强大的电商平台,提供了丰富的主题定制化选项,使您能够个性化您的电商网站外观。在本篇博客中,我们将深入探讨Magento 2主题开发,帮助您定制化网站外观,以满足品牌需求和提供卓越的用户体验。

    首先,我们将介绍Magento 2主题的基本结构和文件组成。了解主题的目录结构、模板文件和布局文件的关系,是进行主题开发的关键。

    接下来,我们将讨论Magento 2主题开发中的样式定制。您将学习如何使用CSS和LESS来修改和定制网站的样式,包括颜色、字体、布局等。我们还将介绍如何使用Magento 2的样式覆盖机制和模块化CSS来避免样式冲突。

    我们还将深入研究Magento 2主题的模板定制。通过修改和定制Magento 2的模板文件,您可以调整网站的布局、块级元素和内容显示。我们将演示如何使用Magento 2的块和容器来构建自定义页面和部分,以及如何使用UI组件来实现交互功能。

    此外,我们将讨论Magento 2主题开发中的响应式设计。了解如何创建响应式的主题,以适应不同设备和屏幕尺寸,将为您的电商网站提供无缝的跨平台体验。

    最后,我们将分享一些Magento 2主题开发的最佳实践和调试技巧。这些实践包括代码规范、调试工具和跨浏览器测试,以确保您开发的主题在各种环境下工作正常。

    通过本篇博客,您将掌握Magento 2主题开发的关键技巧,能够定制化您的电商网站外观,提升品牌形象和用户体验。

    ]]>
    Sun, 31 Dec 2023 08:07:33 +0000
    <![CDATA[Magento布局开发]]> https://www.360magento.com/blog/magento-layout-insights/ 在电商网站的设计和开发过程中,布局起着至关重要的作用。Magento作为一款流行的电商平台,提供了灵活而强大的布局系统,使网站设计人员能够创建具有吸引力和功能性的页面。本文将深入探讨Magento布局的重要性以及如何优化布局以提升电商网站的设计和用户体验。

    1. 了解Magento布局体系结构

    首先,我们将介绍Magento布局体系结构的基本概念。您将了解到Magento布局的层次结构,包括布局文件、块(Blocks)和容器(Containers)的概念。我们将探讨布局文件的作用和结构,并介绍常用的布局文件类型,如XML布局文件和主题布局文件。

    1. 使用布局文件自定义页面结构

    接下来,我们将讨论如何使用Magento的布局文件来自定义页面结构。您将了解如何创建自定义布局文件,并使用布局指令来定义页面上的块和容器。我们将介绍如何在布局文件中引用模板文件和块类,并向您展示如何使用布局文件来组织页面的不同部分和内容。

    1. 利用布局文件进行页面排版和设计

    在本节中,我们将探讨如何使用Magento的布局文件进行页面排版和设计。您将学习如何使用布局指令来定义页面的列和行,以及如何配置块和容器的位置和大小。我们还将介绍如何使用Magento的栅格系统来创建响应式布局,以适应不同的设备和屏幕尺寸。

    1. 优化布局以提升用户体验

    最后,我们将分享一些优化布局的最佳实践,以提升电商网站的用户体验。您将学习如何合理使用布局文件和块来优化页面加载速度,以及如何通过合理的布局设计来提升页面的可用性和易用性。我们还将介绍如何使用Magento的布局更新(Layout Updates)功能来实现页面的动态变化和个性化。

    ]]>
    Sun, 31 Dec 2023 03:21:03 +0000
    <![CDATA[Magento 2缓存优化]]> https://www.360magento.com/blog/optimizing-magento-2-performance/ 作为一款功能强大的电商平台,Magento 2的性能优化对于提供良好的用户体验至关重要。在本篇博客中,我们将分享一些优化Magento 2性能的关键技巧,帮助您加速网站加载速度、提高响应性能,并提升整体用户体验。

    首先,我们将介绍Magento 2的缓存系统。了解如何正确配置和管理Magento 2的缓存设置,包括页面缓存、块级缓存和对象缓存,可以显著减少页面加载时间和数据库负载。

    接着,我们将探讨优化Magento 2的数据库性能。通过优化数据库查询、索引和表结构,您可以提高数据访问速度和响应性能。我们还将介绍工具和技术,如数据库分片和读写分离,用于处理高负载情况下的数据库压力。

    我们还将讨论优化Magento 2前端性能的关键技巧。这包括合并和压缩CSS和JavaScript文件、使用图像优化技术、启用HTTP/2和CDN等,以加快网页加载速度并减少网络请求。

    此外,我们将分享一些针对Magento 2的服务器配置和优化建议。通过正确配置服务器环境、调整PHP和数据库参数,以及使用高性能缓存和反向代理等技术,您可以提升Magento 2的整体性能表现。

    最后,我们将提供一些监测和测试Magento 2性能的工具和方法。通过定期监测和测试,您可以识别瓶颈和性能问题,并采取相应的优化措施。

    通过本篇博客,您将了解到一些关键的技巧和最佳实践,帮助您优化Magento 2的性能,提升网站速度和用户体验。

    ]]>
    Sat, 30 Dec 2023 08:06:39 +0000
    <![CDATA[Magento 2安全性指南]]> https://www.360magento.com/blog/magento-2-security-guide/ 首先,我们将介绍Magento 2的安全功能和设置。这包括使用安全证书(SSL)来加密网站的通信,启用两步验证(2FA)以增强管理员和用户的身份验证,以及配置强密码策略和登录尝试限制来防止恶意登录。

    接着,我们将深入研究Magento 2安全性的主要方面。您将了解到如何保护Magento 2的后台管理页面,包括限制IP访问、使用安全的管理员用户名和密码,以及监控和审计管理员活动。我们还将讨论如何保护Magento 2的数据库,包括加密敏感数据、定期备份和监控数据库的安全性。

    我们还将探讨Magento 2插件和主题的安全性。您将学习如何选择可靠的插件和主题供应商,审查插件和主题的代码质量和安全性,以及定期更新和升级插件和主题以修复安全漏洞。

    此外,我们将介绍一些Magento 2安全性的最佳实践和建议。这些实践包括定期更新Magento 2的核心代码和扩展,使用安全的托管环境和防火墙,定期进行安全性扫描和漏洞评估,以及培训员工和用户有关安全性最佳实践和保护隐私的意识。

    最后,我们将分享一些Magento 2安全性资源和社区支持。您将了解到可以获取安全性文档、漏洞报告和安全更新的官方资源,以及参与Magento 2安全性社区和论坛的机会。

    ]]>
    Sat, 30 Dec 2023 03:16:37 +0000
    <![CDATA[Magento数据库优化]]> https://www.360magento.com/blog/magento-database-optimization/ 数据库是Magento系统关键组成部分,优化它对提升整体性能影响重大。主要优化方面包括:

    1. 索引优化

    根据查询条件添加合理索引,如商品名、分类等字段。

    1. 表结构优化

    调整表字段类型、去除没用字段、合并小表等操作。

    1. 查询优化

    避免表关联深度过多,使用explain分析查询效率。

    1. 缓存查询结果

    对常用数据如商品信息等进行缓存,降低查询次数。

    1. 分表设计

    对数据量大的表 like order_item 分割表。

    1. 数据库参数调优

    优化MySQL参数如查询缓存大小、连接数等。

    1. 数据归档

    定期归档老数据到其他数据库或表,降低活跃表数据量。

    通过系统地进行这些优化,可以显著提升Magento数据库访问效率,对整体系统性能提升很重要。

    ]]>
    Fri, 29 Dec 2023 07:05:47 +0000
    <![CDATA[Magento 2 SEO优化]]> https://www.360magento.com/blog/magento-2-seo-optimization/ 在竞争激烈的电商市场中,优化您的网站以提升搜索排名是至关重要的。Magento 2作为一款流行的电商平台,提供了各种功能和工具来帮助您进行SEO(搜索引擎优化)。在本篇博客中,我们将深入探讨Magento 2的SEO优化策略和技巧,帮助您提升电商网站在搜索引擎中的可见性和排名。

    首先,我们将介绍Magento 2中的基本SEO设置和配置。您将学习如何优化网站的标题(Title)、描述(Meta Description)和关键词(Meta Keywords),以及如何生成友好的URL结构。我们还将讨论如何设置网站地图(Sitemap)和Robots.txt文件,以便搜索引擎能够正确地抓取和索引您的网页。

    接下来,我们将深入探讨Magento 2网页优化的关键因素。这包括优化网页内容、使用关键词和标签、以及创建高质量的产品和类别页面。我们还将介绍如何优化网页的加载速度和性能,以提供更好的用户体验和满足搜索引擎的要求。

    我们还将讨论Magento 2中的技术SEO优化。这包括使用友好的URL重写(URL Rewrites)来消除重复内容和优化链接结构,设置301重定向以处理页面重定向和更改,以及使用Canonical标签来处理重复内容和规范化网页版本。

    除了基本的SEO优化,我们还将介绍一些高级策略和技巧。这包括优化图像和多媒体内容、集成社交媒体和用户生成内容、以及使用结构化数据(Schema Markup)来增强搜索结果的显示。

    最后,我们将分享一些Magento 2 SEO优化的最佳实践和工具。这些实践包括进行关键词研究和竞争分析、定期监测和跟踪搜索排名和流量、以及参与社区和论坛来获取更多的SEO建议和支持。

    ]]>
    Fri, 29 Dec 2023 03:09:06 +0000
    <![CDATA[Magento 2 REST API]]> https://www.360magento.com/blog/mobile-development-with-magento-2-rest-api/ Magento 2提供了完整的RESTful API接口,开发者可以基于此为移动端应用快速开发 order 管理、商品浏览等功能:

    1. 获取Access Token

    调用OAuth接口获取长期有效的访问令牌。

    1. API路由与权限

    了解各API接口地址与需要的权限级别。

    1. 数据模型与实体

    传输的JSON格式与Magento对象对应。

    1. 订单管理API

    创建、更新订单以及查询订单详情状态。

    1. 商品资源API

    搜索、浏览分类和商品详情信息。

    1. 客户资源API

    管理用户地址单和客户账户信息。

    1. 配置API

    获取系统配置如货币的信息。

    1. 异步任务API

    支持定期同步更新订单等后台任务。

    1. 错误处理

    标准化处理各类API调用错误。

    利用REST API可以快速构建跨平台的移动解决方案,有效扩展Magento商城业务。

    ]]>
    Thu, 28 Dec 2023 07:04:43 +0000
    <![CDATA[Magento 2插件开发]]> https://www.360magento.com/blog/magento-2-plugin-development/ Magento 2作为一款功能强大的电商平台,提供了插件开发的灵活性,使您能够扩展和定制化您的电商网站功能。在本篇博客中,我们将深入探讨Magento 2插件开发,帮助您扩展网站功能,满足特定业务需求和提供更好的用户体验。

    首先,我们将介绍Magento 2插件的基本概念和结构。了解插件的目录结构、配置文件和代码组成是进行插件开发的关键。我们还将探讨插件的类型,包括观察者(Observers)、插件(Plugins)和扩展(Extensions),以及它们在Magento 2中的应用场景和用途。

    接下来,我们将深入研究Magento 2插件开发中的关键技术和功能。您将学习如何使用观察者模式来监听和响应Magento 2中的事件,以实现定制化的业务逻辑。我们还将介绍如何使用插件来修改和扩展Magento 2的核心功能,如模型(Models)、控制器(Controllers)和块(Blocks)。

    我们还将讨论Magento 2插件开发中的最佳实践和调试技巧。这些实践包括使用正确的事件和插件顺序、编写干净和可维护的代码、以及使用调试工具和日志记录来排查问题和优化性能。

    除了基本的插件开发,我们还将介绍一些高级功能和应用。这包括创建自定义的插件配置、实现插件的版本控制和升级、以及在多个Magento 2实例之间共享和复用插件。

    最后,我们将分享一些Magento 2插件开发的资源和社区支持。您将了解到可以获取插件开发文档、示例代码和教程的官方资源,以及参与Magento 2开发者社区和论坛的机会。

    ]]>
    Wed, 27 Dec 2023 16:09:06 +0000
    <![CDATA[了解Magento 2的模块开发]]> https://www.360magento.com/blog/magento-2-module-development/ Magento 2是一款功能强大的开源电商平台,广泛应用于各种规模的电商网站。其中,模块开发是扩展和定制Magento 2功能的关键部分。在本篇博客中,我们将深入了解Magento 2的模块开发,为您提供宝贵的指导和技巧。

    首先,我们将介绍Magento 2模块的基本结构和组成部分。了解模块的目录结构、配置文件和代码组织对于正确开发和集成模块至关重要。

    接下来,我们将深入探讨Magento 2模块的事件(Event)和观察者(Observer)系统。通过使用事件和观察者,您可以在Magento 2的各个关键点插入自定义逻辑,实现个性化的功能扩展。

    我们还将介绍Magento 2模块的插件(Plugin)机制。插件提供了一种非侵入性的方式,允许您修改和扩展Magento 2核心类的行为。我们将详细讨论插件的创建、配置和使用。

    此外,我们将研究Magento 2模块的数据库操作和数据迁移。您将学习如何使用Magento 2提供的资源模型和安装脚本来管理数据库结构和数据。

    最后,我们将分享一些Magento 2模块开发的最佳实践。这些实践包括代码质量、性能优化和安全性等方面的建议,以确保您开发的模块在生产环境中稳定可靠。

    ]]>
    Wed, 27 Dec 2023 07:03:44 +0000
    <![CDATA[Magento 2数据迁移]]> https://www.360magento.com/blog/comprehensive-guide-magento-2-data-migration/ 在将您的电商网站迁移到Magento 2平台时,数据迁移是一个至关重要的任务。为了帮助您顺利迁移数据并确保数据完整性,本篇博客将提供Magento 2数据迁移的综合指南,涵盖关键步骤、工具和最佳实践。

    首先,我们将介绍Magento 2数据迁移的准备工作。这包括了解您当前网站的数据结构、数据库和文件系统,以及评估迁移的范围和复杂性。我们还将讨论如何创建备份和快照,以防止数据丢失或损坏。

    接下来,我们将深入探讨Magento 2数据迁移的不同方法。您将了解到使用Magento 2的数据迁移工具(Data Migration Tool)的步骤和流程。我们还将介绍如何使用第三方迁移工具和扩展,以满足特定的迁移需求。

    我们将讨论Magento 2数据迁移中的常见挑战和解决方案。这包括处理数据格式的不兼容性、解决数据库架构差异、以及处理自定义模块和功能的迁移问题。我们还将提供一些建议和技巧,帮助您克服潜在的问题和障碍。

    除了基本的数据迁移,我们还将介绍如何迁移其他关键数据,如产品、订单、客户和库存。您将学习如何映射和转换数据字段、处理数据关联性、以及确保数据的一致性和准确性。

    ]]>
    Wed, 27 Dec 2023 03:09:06 +0000
    <![CDATA[Magento 2与跨境电子商务]]> https://www.360magento.com/blog/magento2-cross-border-ecommerce-strategies/ 随着全球化和数字化的推进,跨境电子商务成为许多商家拓展市场的重要途径。作为一种功能丰富的电子商务平台,Magento 2为商家提供了一系列跨境电子商务策略和扩展功能,帮助他们克服跨境交易中的挑战,并实现全球销售。在本文中,我们将探讨一些适用于Magento 2的跨境电子商务策略和扩展。

    1. 多语言和多货币支持:利用Magento 2的多语言和多货币功能,将您的网站本地化以适应不同的目标市场。提供多种语言选项和货币转换功能,可以提高用户的舒适度和购买意愿。

    2. 地理定位和本地化:通过使用地理定位技术和本地化策略,向用户提供与其所在地区相关的内容、价格和优惠。根据用户的位置和IP地址,自动调整货币、税率和运费等信息,提高用户的购买体验和转化率。

    3. 国际物流和运输:整合Magento 2与全球物流服务提供商,以简化跨境物流和运输过程。提供多个物流选项、实时运费计算和订单追踪功能,确保订单能够快速、可靠地送达全球各地。

    4. 海关和税务合规性:了解目标市场的海关和税务规定,并确保您的Magento 2网站符合当地的法规要求。提供正确的产品分类、税率计算和报关文件,以避免海关问题和税务纠纷。

    5. 支付和结算:提供多种跨境支付选项,如信用卡支付、电子钱包和本地化支付解决方案。整合安全可靠的支付网关,并确保支付过程符合当地的支付安全标准和合规要求。

    6. 跨境营销和推广:针对不同的目标市场制定跨境营销和推广策略。利用Magento 2的市场营销工具和功能,如SEO优化、社交媒体整合和跨境广告活动,增加品牌曝光和用户参与度。

    7. 多国家客户支持:提供多语言的客户支持和售后服务,以满足不同国家和地区的用户需求。设立多语言的客服团队,并提供在线聊天、电子邮件和电话支持等渠道,解答用户的疑问和处理问题。

    8. 跨境数据分析和优化:利用Magento 2的数据分析工具和仪表板,深入了解不同国家和地区的市场表现和用户行为。根据数据结果进行优化和改进,调整产品定价、市场定位和营销策略,以提高跨境电子商务的效果和回报率。

    通过采用上述Magento 2中的跨境电子商务策略和扩展,您可以充分利用全球市场的机会,并实现全球范围内的业务增长。

    ]]>
    Tue, 26 Dec 2023 08:20:32 +0000
    <![CDATA[Magento 2中的安全性]]> https://www.360magento.com/blog/mmagento2-security-measures/ 作为一款广受欢迎的电子商务平台,Magento 2提供了一系列强大的安全性措施和最佳实践,以保护您的网站和客户的敏感信息免受潜在的威胁。在本文中,我们将介绍一些适用于Magento 2的关键安全性措施和建议。

    1. 及时更新Magento版本:确保您的Magento 2平台及其相关扩展和插件始终使用最新的安全补丁和更新版本。定期检查Magento官方网站和社区,以获取最新的安全性公告和建议,并遵循官方的升级指南。

    2. 强化管理员访问控制:采取措施限制对Magento管理员后台的访问。创建强密码并定期更改密码,使用双因素身份验证增加额外的安全层级,并仅授予必要的管理员权限给相关人员。

    3. 安全的扩展和主题:仅从官方Magento Marketplace或可信的第三方开发者处获取和安装扩展和主题。审查扩展和主题的评分、用户评论和开发者声誉,并确保它们是经过安全审计和测试的。

    4. 进行安全扫描和漏洞测试:定期进行Magento网站的安全扫描和漏洞测试,以检测潜在的漏洞和弱点。使用安全扫描工具和服务来评估您的网站的安全性,并及时修复发现的问题。

    5. 数据备份和恢复计划:定期备份Magento 2网站的数据,并确保备份数据存储在安全的位置。创建详细的数据恢复计划,以便在发生数据丢失或系统故障时能够快速恢复网站功能。

    6. 安全的支付和敏感信息保护:采用安全的支付网关和加密技术,以保护客户的支付信息和敏感数据。确保您的网站使用HTTPS协议进行安全的数据传输,并遵守PCI DSS(支付卡行业数据安全标准)的合规要求。

    7. 监控和日志记录:设置实时监控和日志记录系统,以及时检测和记录异常活动。监测登录尝试、访问模式和异常行为,并建立警报机制,以便在发生安全事件时能够及时采取行动。

    8. 培训和意识提升:定期为您的团队提供安全意识培训,教育他们识别和应对潜在的网络威胁。强调密码安全、社会工程学攻击和恶意软件防范等关键安全概念。

    通过采用上述Magento 2中的安全性措施和最佳实践,您可以提高您的网站和客户数据的安全性,并降低潜在的安全风险和漏洞。

    ]]>
    Tue, 26 Dec 2023 03:22:47 +0000
    <![CDATA[Magento 2中的优化建议]]> https://www.360magento.com/blog/magento2-mobile-optimization/ 随着移动设备的普及和用户购物行为的变化,为移动用户提供优质的体验变得至关重要。作为一种功能强大的电子商务平台,Magento 2提供了一系列移动优化策略和最佳实践,以确保您的网站在移动设备上获得卓越的性能和用户体验。在本文中,我们将分享一些适用于Magento 2的移动优化策略和技巧。

    1. 响应式网站设计:采用响应式网站设计,确保您的Magento 2网站能够自适应不同大小的移动设备屏幕。响应式设计可以提供一致的用户体验,并避免为每个设备单独创建独立的网站版本。

    2. 移动友好的用户界面:优化您的Magento 2网站的用户界面,使其在移动设备上易于导航和操作。确保按钮和链接足够大,并避免使用弹出窗口和复杂的表单输入,以提高用户的互动和转化率。

    3. 加速网站加载速度:移动设备通常具有较低的带宽和处理能力,因此优化您的Magento 2网站以提高加载速度至关重要。压缩图像、减少HTTP请求、优化CSS和JavaScript文件,并启用浏览器缓存等措施,可以显著提升移动网站的性能。

    4. 移动支付选项:为移动用户提供多种方便快捷的支付选项,如移动钱包、支付宝、微信支付等。简化结账流程,并确保移动支付体验安全可靠,以提高用户的购买转化率。

    5. 移动搜索优化:优化您的Magento 2网站以适应移动搜索引擎的需求。重点关注移动关键词和本地化搜索,确保您的网站内容对移动用户具有高度相关性和可见性。

    6. 视频和图像优化:在移动设备上播放视频和加载图像可能会消耗用户的流量和时间。优化视频和图像的大小和格式,以提供高质量的视觉体验,同时减少加载时间和数据消耗。

    7. 移动推送通知:利用Magento 2的移动推送通知功能,向用户发送个性化的促销和重要信息。通过向移动用户发送定制化的通知,您可以增加用户参与度和购买动力。

    8. 移动设备测试:确保定期在各种移动设备上测试您的Magento 2网站。检查页面布局、功能和用户体验,并解决任何移动设备兼容性问题,以提供一致的优质体验。

    通过采用上述Magento 2中的移动优化策略和最佳实践,您可以提供出色的移动用户体验,并吸引更多移动用户进行购买和交互。

    ]]>
    Mon, 25 Dec 2023 08:18:44 +0000
    <![CDATA[Magento中的搜索引擎优化(SEO)策略和技巧]]> https://www.360magento.com/blog/magento-seo-strategies/ 在竞争激烈的电子商务领域中,将您的Magento网站优化为搜索引擎友好的是吸引更多有针对性的流量和提升在线可见性的关键。通过采用一系列的搜索引擎优化(SEO)策略和技巧,您可以提高您的Magento网站在搜索引擎结果页面中的排名。在本文中,我们将介绍一些适用于Magento的SEO策略和最佳实践,帮助您最大程度地优化您的网站。

    1. 关键词研究和优化:通过进行关键词研究,确定与您的产品和业务相关的关键词和短语。将这些关键词合理地应用于您的Magento网站的页面标题、元描述、URL和内容中,以帮助搜索引擎了解您的网站内容和关键主题。

    2. 优化页面元素:确保每个页面都具有唯一且相关的页面标题和元描述。使用有意义的标题标签(H1、H2等)来组织页面内容,并优化页面URL以反映关键词和内容。

    3. 内部链接优化:在您的Magento网站内部进行链接优化,以建立页面之间的相关性和内部权重传递。使用有关键词的锚文本链接相关页面,并创建一个清晰的网站结构,使搜索引擎和用户都可以轻松导航和理解您的网站。

    4. 图像优化:对您的Magento网站中的图像进行优化,包括使用描述性的文件名和替代文本(ALT文本),以帮助搜索引擎理解图像内容。还可以压缩图像文件大小,以提高页面加载速度。

    5. 用户友好的URL结构:使用简洁、描述性和用户友好的URL结构,包括关键词和相关信息。避免使用复杂的参数和动态URL,优先选择静态URL。

    6. 网站速度优化:优化您的Magento网站以提高页面加载速度。压缩CSS和JavaScript文件,启用浏览器缓存,优化图像大小,减少HTTP请求等,以提供更快的用户体验和搜索引擎的偏好。

    7. 社交媒体整合:在您的Magento网站上集成社交媒体分享按钮,并确保您的网站内容易于分享和传播。社交媒体的参与和分享可以增加您的网站的曝光度和流量。

    8. 定期监测和优化:使用分析工具来跟踪您的Magento网站的搜索引擎排名、流量来源和用户行为。根据数据结果,进行定期的优化和调整,以持续改进您的SEO策略和网站性能。

    通过采用上述Magento中的搜索引擎优化(SEO)策略和技巧,您可以提升您的网站在搜索引擎中的排名,吸引更多有针对性的流量,并提升在线业务的成功。

    ]]>
    Sun, 24 Dec 2023 07:24:30 +0000
    <![CDATA[Magento 2中提高电子商务转化率的关键策略]]> https://www.360magento.com/blog/magento2-conversion-rate-strategies/ 在竞争激烈的电子商务市场中,提高转化率是每个在线商家的关键目标之一。Magento 2作为一种功能强大且灵活的电子商务平台,为商家提供了许多工具和功能来增加销售和转化率。在本文中,我们将分享一些提高您的Magento 2网站转化率的关键策略和技巧。

    1. 简化购物体验:确保您的Magento 2网站的购物流程简单、直观且无缝。简化注册和结账过程,减少步骤和信息输入的要求,提供多种支付选项,并优化移动设备上的用户体验。简化购物体验可以减少购物车放弃率,并增加转化率。

    2. 提供个性化推荐:利用Magento 2的个性化推荐功能,向用户展示与他们兴趣和购买历史相关的产品。通过根据用户的喜好和行为提供相关的产品建议,可以增加交叉销售和重复购买的机会。

    3. 优化产品页面:确保您的产品页面具有清晰的产品图像、吸引人的描述和详细的规格信息。使用高品质的图像和视频展示产品,提供清晰的产品描述和特色,以吸引用户并增加他们的购买决策。

    4. 引入客户评价和社交证明:在您的Magento 2网站上添加客户评价和社交证明,如用户评论、评级和社交媒体分享。积极的客户评价和社交证明可以增加信任度,促使其他用户进行购买决策。

    5. 使用优惠和促销:利用Magento 2的优惠和促销功能,提供吸引人的优惠、折扣和奖励计划。通过限时促销、买一送一和积分奖励等策略,刺激用户的购买欲望,并增加转化率。

    6. 实施购物车提醒:在用户离开购物车而没有完成购买时,通过电子邮件或弹出窗口提醒他们购物车中的待购商品。这可以提醒用户并鼓励他们完成交易,减少购物车放弃率。

    7. 优化网站加载速度:确保您的Magento 2网站具有快速的加载速度,以提供流畅的用户体验。优化图像大小、合并和压缩CSS和JavaScript文件、启用浏览器缓存等措施可以提高网站的加载速度,减少用户的等待时间。

    8. 数据驱动的优化:利用Magento 2的分析工具和报告,深入了解用户行为和转化率数据。根据数据结果进行优化和测试,如A/B测试、多变量测试等,以不断改进您的网站和营销策略。

    通过采用上述关键策略和技巧,您可以提高您的Magento 2网站的转化率,增加销售和业务成功。记住,持续的测试、优化和关注用户反馈是实现持续改进的关键。

    ]]>
    Sun, 24 Dec 2023 03:27:23 +0000
    <![CDATA[Magento中的用户体验优化策略和最佳实践]]> https://www.360magento.com/blog/magento-user-experience-optimization/ 提供卓越的用户体验是在竞争激烈的电子商务市场中脱颖而出的关键。当用户访问您的Magento网站时,他们期望流畅的浏览体验、易于导航的界面和简单的购物过程。在本文中,我们将介绍一些Magento中的用户体验优化策略和最佳实践,帮助您提供令人满意的用户体验并提升转化率。

    1. 响应式设计:确保您的Magento网站具有响应式设计,可以自适应不同的设备和屏幕尺寸,包括桌面电脑、平板电脑和移动设备。这样可以确保用户在任何设备上都能获得一致的优质体验。

    2. 简化导航和布局:设计清晰、直观的导航结构,使用户能够轻松找到他们所需的产品和信息。使用易于理解的标签和菜单,并确保页面布局整洁、有序,减少混乱和冗余的元素。

    3. 快速加载速度:优化您的Magento网站以提高页面加载速度。压缩图像、合并和缓存CSS和JavaScript文件,并优化服务器响应时间,确保用户在访问您的网站时能够获得快速的响应和流畅的浏览体验。

    4. 简化购物流程:简化Magento网站的购物流程,使用户能够快速、方便地完成购买。减少步骤和填写字段的数量,提供多种支付选项,并确保购物车和结账过程清晰明了。

    5. 强调产品和内容:突出展示您的产品和内容,使用高质量的图像和详细的产品描述。提供用户评价和评论,以增加购买决策的信任度和可靠性。

    6. 个性化推荐:利用Magento的个性化推荐功能,根据用户的兴趣和行为推荐相关的产品和内容。这样可以提高用户的参与度和购买意愿。

    7. 多语言和多货币支持:如果您的目标市场跨越多个地区和语言,确保您的Magento网站支持多语言和多货币。这样可以为用户提供更个性化和便利的体验。

    8. 用户反馈和支持:提供易于访问的用户反馈渠道,如在线聊天、联系表单或客户支持热线。及时回应用户的问题和反馈,并持续改进用户支持体系。

    通过采用上述Magento中的用户体验优化策略和最佳实践,您可以提升您的网站的用户满意度,增加用户参与度,并提高转化率和客户忠诚度。

    请记住,用户体验是一个不断演进的过程,需要不断地监测和改进。定期评估和优化您的Magento网站,以满足用户的期望和不断变化的市场需求。

    ]]>
    Sat, 23 Dec 2023 07:20:01 +0000
    <![CDATA[Magento中的安全性最佳实践和保护策略]]> https://www.360magento.com/blog/magento-securitys-best-practices/ 保护您的Magento网站免受潜在的安全威胁是至关重要的。在今天的数字环境中,电子商务网站成为了黑客攻击的目标。为了确保您的Magento网站和客户数据的安全,您需要采取一系列的安全性最佳实践和保护策略。在本文中,我们将介绍一些Magento中的安全性最佳实践,帮助您加强网站的安全性。

    1. 及时更新Magento版本:确保您的Magento网站始终运行最新版本的软件。Magento定期发布安全更新和补丁程序,以修复已知的漏洞和弱点。定期检查并应用这些更新,以确保您的网站免受已知漏洞的影响。

    2. 强化管理员访问:限制对Magento后台的访问权限,仅授权给必要的管理员用户。使用强密码和两步验证等安全措施,确保只有授权的用户能够登录和管理网站。

    3. 安全备份策略:定期备份您的Magento网站和数据库,并将备份存储在安全的位置。这样可以在发生安全事件或数据丢失时快速恢复网站功能。

    4. 安全扩展和主题:在安装任何Magento扩展或主题之前,确保它们来自可信赖的来源,并经过安全审查。仔细评估扩展和主题的代码质量和安全性,以避免安全漏洞和后门。

    5. 强化网络安全:使用防火墙和入侵检测系统来保护您的Magento服务器免受未经授权的访问和恶意攻击。定期监测服务器日志和网络活动,及时检测异常行为。

    6. 安全的支付处理:确保您的Magento网站采用安全的支付处理方式,如使用SSL证书加密用户与网站之间的通信,以保护敏感的支付信息。

    7. 安全审计和监测:定期进行安全审计和漏洞扫描,以识别潜在的安全风险和漏洞。使用安全监测工具来实时监测您的Magento网站,及时发现和应对任何安全威胁。

    8. 培训和意识提升:培训您的团队成员,包括管理员和开发人员,关于Magento安全性最佳实践和对抗潜在威胁的方法。增强员工的安全意识和敏感性,以确保他们能够正确处理安全问题和紧急情况。

    通过采用上述Magento中的安全性最佳实践和保护策略,您可以加固您的网站的安全防线,降低潜在风险,并保护您的客户数据和业务利益。

    请记住,安全是一个持续的过程,需要定期评估和更新。随着安全威胁的不断演变,您需要保持警惕并及时采取相应的安全措施。

    ]]>
    Sat, 23 Dec 2023 03:23:07 +0000
    <![CDATA[Magento中的SEO最佳实践和优化策略]]> https://www.360magento.com/blog/magento-seo-best-practices/ 在竞争激烈的电子商务市场中,优化您的Magento网站以提高搜索引擎排名对于吸引更多的有机流量和增加销售至关重要。在本文中,我们将介绍一些Magento中的SEO最佳实践和优化策略,帮助您在搜索引擎结果页面上脱颖而出。

    1. 关键字研究和优化:进行深入的关键字研究,了解您的目标受众在搜索引擎中使用的关键字。将这些关键字合理地应用于您的网站内容、标题、元标签和URL中,以提高页面的相关性和可发现性。

    2. 优化网站结构:确保您的Magento网站具有清晰的网站结构和导航层次。使用有意义的目录结构和URL结构,使搜索引擎和用户能够轻松浏览和理解您的网站。

    3. 内容优化:编写高质量、原创和有价值的内容是吸引搜索引擎和用户的关键。在您的Magento网站上创建有吸引力的产品描述、博客文章和页面内容,并确保关键字的自然集成。

    4. 图像优化:优化您的产品图像以提高搜索引擎的可索引性。使用描述性文件名和ALT标签,并压缩图像以提高页面加载速度。

    5. 友好的URL结构:使用有意义和描述性的URL,包含关键字,并避免使用动态参数。优化URL可以提高搜索引擎对页面的理解和排名。

    6. 网站速度优化:确保您的Magento网站具有快速的加载速度,以提供良好的用户体验并获得更好的搜索引擎排名。压缩和合并CSS和JavaScript文件,优化图像,并使用缓存和CDN等技术来减少页面加载时间。

    7. 社交媒体整合:将您的Magento网站与社交媒体平台整合,以增加社交分享和品牌曝光。通过分享按钮和社交媒体链接,鼓励用户与您的网站内容进行互动和分享。

    8. 持续监测和优化:使用工具如Google Analytics来监测您的Magento网站的关键指标,如流量来源、页面访问量和转化率。根据数据分析结果,优化您的SEO策略和网站内容,以实现更好的结果。

    通过采用上述Magento中的SEO最佳实践和优化策略,您可以提高您的网站在搜索引擎中的可见性和排名,吸引更多的有机流量,并增加销售和转化率。

    ]]>
    Fri, 22 Dec 2023 07:18:33 +0000
    <![CDATA[Magento中的安全性最佳实践和保护策略]]> https://www.360magento.com/blog/magento-security-best-practices/ 保护您的Magento电子商务网站免受安全威胁是至关重要的。在今天的数字时代,保护客户数据、防止恶意攻击和确保网站的安全性是您作为网站所有者的首要任务。在本文中,我们将介绍一些Magento中的安全性最佳实践和保护策略。

    1. 使用最新的Magento版本:始终使用最新的Magento版本,以确保您能够获得最新的安全更新和补丁程序。Magento持续发布安全更新,以解决已知的漏洞和强化系统的安全性。

    2. 强化管理员访问控制:限制对Magento后台的访问,并为管理员分配强密码和唯一的用户名。另外,使用双因素身份验证(2FA)来提供额外的安全层级。

    3. 安全的主机环境:选择可信赖的主机提供商,并确保他们提供安全的服务器环境。确保服务器上的操作系统、数据库和软件都得到及时更新和安全配置。

    4. 使用SSL加密:为您的Magento网站启用SSL证书,通过HTTPS协议来加密用户的敏感数据传输。这样可以防止中间人攻击和数据泄露,并为用户提供更安全的购物环境。

    5. 定期备份和恢复测试:定期备份Magento网站的数据库和文件,并进行恢复测试,以确保备份的可用性和完整性。这样可以在发生数据丢失或系统故障时快速还原网站。

    6. 安全扩展和主题:仅从可靠和受信任的源获取Magento扩展和主题。确保它们经过安全审查,并且来自可靠的供应商。定期更新和升级扩展和主题以获取最新的安全修复和功能改进。

    7. 监控和日志记录:启用Magento的日志记录功能,并监控网站的活动和访问。设置警报系统以及实时监控和检测潜在的安全威胁。

    8. 安全意识培训:培训您的团队,包括管理员和员工,以提高安全意识和识别潜在的网络威胁。教育他们关于密码安全、社交工程攻击和恶意软件防护等方面的最佳实践。

    通过采用上述Magento安全性最佳实践和保护策略,您可以大大提高您的电子商务网站的安全性,降低潜在的风险,并保护用户数据的机密性和完整性。

    ]]>
    Thu, 21 Dec 2023 16:16:11 +0000
    <![CDATA[如何在Magento中优化电子商务网站的性能]]> https://www.360magento.com/blog/magento-performance-optimizations/ 电子商务网站的性能优化对于提供卓越的用户体验、提高转化率和搜索引擎排名至关重要。在Magento中,有许多优化措施可以帮助您提升网站的性能。在本文中,我们将介绍一些Magento中优化电子商务网站性能的最佳实践。

    1. 使用全页缓存(Full Page Cache):Magento提供了全页缓存功能,通过缓存整个页面,可以显著提高页面加载速度。启用全页缓存并配置适当的缓存策略,可以减少数据库查询和动态页面生成的次数,从而提高性能。

    2. 压缩和合并CSS和JavaScript:将多个CSS和JavaScript文件合并为较少的文件,并使用压缩工具来减小文件大小。这样可以减少HTTP请求次数并提高页面加载速度。Magento提供了内置的资源合并和压缩功能,您可以在Magento后台启用它们。

    3. 优化图像:优化图像可以减少页面的加载时间。使用适当的图像格式(如JPEG、PNG)并压缩图像以减小文件大小。同时,使用图像的响应式设计,根据设备屏幕的大小提供适当尺寸的图像,避免无谓的带宽浪费。

    4. 使用CDN(内容分发网络):通过使用CDN,您可以将网站的静态资源(如图像、CSS和JavaScript文件)分发到全球各地的服务器,从而实现更快的加载速度。选择一个可靠的CDN提供商,并将Magento配置为使用CDN来提供静态资源。

    5. 优化数据库:通过优化数据库表结构、使用索引和定期清理日志等方法,可以改善Magento网站的性能。使用Magento提供的数据库优化工具或借助第三方扩展来执行这些优化操作。

    6. 考虑使用缓存扩展:Magento还提供了许多缓存扩展,如Redis、Memcached等。这些扩展可以提供更高效的缓存存储和读取,进一步提升网站的性能。

    通过采用上述优化措施,您可以显著提升Magento电子商务网站的性能,提供更好的用户体验,并为您的业务增加竞争力。

    请注意,这只是一些Magento性能优化的基本建议,实际的优化策略可能因网站的特定需求和配置而有所不同。建议在进行任何更改之前,先在测试环境中进行测试和验证。

    ]]>
    Thu, 21 Dec 2023 07:11:54 +0000
    <![CDATA[Magento中的移动优化策略和最佳实践]]> https://www.360magento.com/blog/magento-mobile-optimization/ 移动设备的普及使得移动优化对于电子商务网站至关重要。在Magento中,实施有效的移动优化策略可以提升用户体验、增加转化率,并提高搜索引擎排名。在本文中,我们将介绍一些Magento中的移动优化策略和最佳实践。

    1. 响应式设计:使用响应式设计来确保您的Magento网站在各种移动设备上都能够提供良好的用户体验。响应式设计可以根据设备屏幕的大小和分辨率自动调整网站的布局和样式,使其适应不同的屏幕尺寸。

    2. 移动友好的导航:精简和简化导航栏是移动优化的关键。确保导航栏在移动设备上易于操作,并提供简洁的菜单结构,以便用户能够轻松浏览和导航网站。

    3. 快速加载速度:移动设备通常具有较低的带宽和处理能力,因此快速加载速度对于移动优化至关重要。通过压缩和合并CSS和JavaScript文件、优化图像、启用缓存以及使用CDN等技术来减少页面加载时间。

    4. 简化结账流程:移动设备上的结账流程应尽可能简化和优化。减少步骤和输入字段,并提供易于填写的表单和选择器,以提高移动用户的结账转化率。

    5. 移动支付选项:提供多种移动支付选项,如移动钱包、支付宝、微信支付等,以满足移动用户的支付需求,并提高购物车转化率。

    6. 点击目标和按钮设计:确保按钮和点击目标具有足够的大小,以便在触摸屏上轻松点击。调整按钮样式和间距,以便移动用户可以轻松识别和操作。

    7. 测试和优化:在实施移动优化策略之前,进行适当的测试是必要的。使用移动设备和模拟器测试网站的响应性、布局和功能,并根据测试结果进行优化和改进。

    通过采用上述Magento移动优化策略和最佳实践,您可以提升移动用户的体验,增加转化率,并确保您的网站在移动设备上获得更好的可见性和排名。

    请注意,移动优化是一个持续的过程,需要定期监测和优化。建议根据您的网站和用户需求,定期评估和改进移动优化策略。

    ]]>
    Wed, 20 Dec 2023 16:14:53 +0000
    <![CDATA[借助主题优化工具提升Magento模板效率]]> https://www.360magento.com/blog/enhance-magento-theme-development-with-tools/ 专注开发主题对提升Magento店铺用户体验很重要。为了提高开发效率,可以使用下列主题优化工具:

    1. Less/Sass编译器:比如Dart Sass支持变量、混合、导入等特性,简化CSS书写。

    2. 工程化工具:如Webpack打包主题资源,自动处理依赖、样式重用等任务。

    3. 部件库:像Magento UI提供了一套基础组件,减少重复开发工作。

    4. 主题开发插件:示例VSCode插件支持智能感知Magento路径、代码补全等。

    5. 模板引擎:例如Pug/Twig可读性好,有效提高模板效率。

    6. 图片优化:TinyPNG等在线服务可以自动压缩主题图片质量与体积。

    7. 原型设计工具:Axure或Zeplin可在设计阶段预览主题效果。

    8. 测试工具:Karma或WebDriver测试模板静动态脚本。

    使用这些功能强大的主题开发助手,可以更专注于商业需求,开发出高质量主题。

    ]]>
    Wed, 20 Dec 2023 07:09:59 +0000
    <![CDATA[遵循这些Magento开发最佳实践提高项目质量]]> https://www.360magento.com/blog/magento-development-best-practices/ 开发高质量的Magento项目需要遵循一些开发流程上的最佳实践,包括:

    1. 项目设计阶段要定义清晰的架构蓝图和规范。

    2. 开发前准备好项目环境、依赖和开发工具。

    3. 每个功能区块使用模块化思想进行解耦开发。

    4. 基于接口编程,使用依赖注入降低耦合。

    5. 定义完善的命名标准和注释规范。

    6. 使用Git版本控制并实施规范的版本管理流程。

    7. 开发过程中实施中间代码检查和各种测试。

    8. 发布代码前进行严格的质量检测与评审。

    9. 开发文档与代码同步,给新人提供参考。

    10. 监控线上环境并定期进行维护迭代更新。

    严格遵循以上最佳实践可以进一步提高项目质量和可控性。这也是每位Magento开发者都应追求的目标。

    ]]>
    Wed, 20 Dec 2023 03:10:44 +0000
    <![CDATA[搭建基于Magento 2的PWA应用]]> https://www.360magento.com/blog/building-pwa-with-magento-2/ 正如我们所知,PWA(渐进式网络应用)可以将移动应用的用户体验带到网上,它利用了Service Worker、HTTP/2等现代Web技术。

    在Magento2中构建PWA应用需要以下步骤:

    1. 引入PWA Studio库。它包含构建PWA必需的依赖和配置。

    2. 添加Manifest文件。定义应用名称、图标、启动页面等元数据。

    3. 设置Service Worker。用于缓存依赖资源,实现离线访问能力。

    4. 使用前端框架。例如React构建单页应用体验页面。

    5. 集成推送通知。使用Web Push API给用户发送推送。

    6. 主题和部署配置。专门为移动端定制界面样式和优化部署。

    7. 性能监控和优化。分析打包大小、命中率等指标。

    8. A/B测试和迭代。在PWA Studio中支持实验发布机制。

    以上实现可让Magento商城应用拥有原生APP体验,大幅提升用户粘性。这将是未来一条重要的发展方向。

    ]]>
    Tue, 19 Dec 2023 07:18:48 +0000
    <![CDATA[如何系统化开发优质的Magento模块]]> https://www.360magento.com/blog/systematic-magento-module-development/ 开发Magento模块需要遵循清晰的原则,以下几点可以帮助系统化提质量:

    1. 设计模块功能和架构

    2. 使用组件化思想划分模块

    3. 注重模块解耦和服务分层

    4. 声明模块配置和依赖

    5. 开发基于接口的模块类

    6. 使用Factory和Repository模式

    7. 定义通用模块事件与观察者

    8. 使用注解完成IoC绑定

    9. 编写单元与集成测试用例

    10. 规范代码样式与注释

    11. 发布模块到Composer仓库

    12. 持续迭代与优化模块

    遵循这些建议可以打造模块功能强大、测试覆盖率高、质量可靠。这将给用户提供一流的开发体验。

    ]]>
    Tue, 19 Dec 2023 03:21:10 +0000
    <![CDATA[如何在Magento中优化电子商务网站的性能]]> https://www.360magento.com/blog/magento-performance-optimization/ Magento是一种功能强大的电子商务平台,但在处理大量产品和高流量时,可能会面临性能方面的挑战。优化Magento网站的性能对于提供良好的用户体验、提高转化率和搜索引擎排名至关重要。在本文中,我们将介绍一些优化Magento网站性能的最佳实践。

    1. 选择合适的主机:选择一个可靠且专门针对Magento优化的主机提供商,确保您的网站能够获得足够的服务器资源和性能。

    2. 使用全页缓存:Magento提供了一个全页缓存功能,它可以缓存整个页面,从而提高页面加载速度。确保启用并配置全页缓存以获得最佳性能。

    3. 优化图像:优化图像可以大幅度减少页面加载时间。使用适当的图像格式(如JPEG、PNG)并压缩图像以减小文件大小。还可以使用懒加载技术,在用户滚动到图像时再加载它们。

    4. 合并和压缩CSS和JavaScript:将多个CSS和JavaScript文件合并为较少的文件,并使用压缩工具来减小文件大小。这将减少HTTP请求次数并提高页面加载速度。

    5. 使用CDN

    ]]>
    Mon, 18 Dec 2023 07:13:32 +0000
    <![CDATA[提升Magento网站访问速度的7个有效方式]]> https://www.360magento.com/blog/7-ways-to-boost-magento-site-performance/ 随着电商业务量的增长,网站访问性能优化变得尤为重要。这里介绍7个可以有效提升Magento速度的方法:

    1. 浏览器缓存静态资源

    正确配置Expires头和缓存策略,让浏览器长期缓存JavaScript、CSS、图片等静态文件。

    1. CDN加速静态内容访问

    使用内容分发网络(CDN)将静态文件部署至就近节点,大幅减少下载时间。

    1. 数据库和对象缓存

    利用Memcached/Redis缓存常用数据库查询和模型访问,降低数据库压力。

    1. 页面缓存

    通过Varnish或FPC对频繁访问页面进行缓存,只在必要时才重新生成HTML。

    1. 数据库索引优化

    根据查询需求添加合理索引,提升数据库查询效率。

    1. JS和CSS合并压缩

    合并JavaScript和CSS文件,减少HTTP请求数,同时压缩ToFile大小。

    1. 错误日志和访问日志分析

    分析错误日志排查性能问题,优化访问热点流量瓶颈。

    贯彻应用以上方法可以在很大程度上提升Magento网站的整体性能,提升用户体验。

    ]]>
    Mon, 18 Dec 2023 03:16:33 +0000
    <![CDATA[全面了解Magento扩展开发的重要概念]]> https://www.360magento.com/blog/important-concepts-for-magento-extension-development/ 正如之前所介绍的,开发扩展是给Magento网站添加新功能的主要方式。要深入掌握扩展开发,有必要了解其中的一些关键概念:

    模块(Module)

    这个是Magento扩展的基本单位,每个扩展都是一个模块。它封装了完整的功能逻辑和资源。

    配置(Configuration)

    模型(Model)

    资源模型(Resource Model)

    集合(Collections)

    块(Block)

    控制器(Controller)

    事件观察者(Event/Observer)

    配置风格(Configuration Types)

    这些建构扩展的基础概念都需要掌握,将有助于设计出高内聚的架构。后续还可以关注测试、打包等工程实践。

    ]]>
    Sun, 17 Dec 2023 07:12:52 +0000
    <![CDATA[从零开始构建你的第一个Magento扩展]]> https://www.360magento.com/blog/how-to-build-your-first-magento-extension/ 如果你想给Magento网站添加新的功能特性,最简单直接的方法就是开发一个Magento扩展模块。本文将分步给出构建简单Magento扩展的入门过程:

    1. 创建基本文件结构

    2. 注册模块

    3. 创建模型类

    4. 定义数据库表

    5. 定义控制器

    6. 创建配置文件

    7. 定义模板文件

    8. 测试与调试

    9. 打包发布

    此流程快速为你构建了一个简单的工作扩展。熟悉后可以根据实际需求进行功能充实。

    ]]>
    Sun, 17 Dec 2023 03:00:00 +0000
    <![CDATA[如何进行有效的Magento模块测试]]> https://www.360magento.com/blog/effective-testing-for-magento-modules/ 测试工作对保证Magento模块质量极为重要。这里介绍几种常用的Magento模块测试方法:

    • 单元测试:使用PHPUnit测试模块类、函数等单个逻辑单元,检查输入输出是否符合预期。

    • 集成测试:测试模块间交互是否正常,如调用其它模块功能流程。此类测试需要模拟完整环境。

    • 功能测试:从用户视角测试模块关键功能是否可用,如从前端提交表单数据流程。可使用Selenium自动化测试。

    • 验收测试:在实际业务场景下,验证模块是否满足原先设计的功能需求规格。

    • 回归测试:发布新版本后,重新运行历史用例以防新问题。

    • 性能测试:使用工具测试模块性能指标,如响应时间是否在合理范围。

    • 安全测试:通过fuzz测试与漏洞扫描测试模块安全强度。

    • 本地测试:在开发环境下运行AutoTests套件进行快速测试。

    • 线上测试:在测试环境或线上真实数据下进行黑盒测试。

    持续完善模块测试套件,保证各种场景下都有覆盖性,给开发带来靠谱的 feedback,也能在发布前锤炼代码质量。测试工作需要在全生命周期贯穿始终。

    ]]>
    Sat, 16 Dec 2023 07:09:01 +0000
    <![CDATA[使用这些工具提升Magento网站的效能]]> https://www.360magento.com/blog/tools-for-magento-performance-optimization/ 性能优化对每个Magento网站都很重要。这里介绍几种有效的工具可以帮助优化Magento性能:

    • Google PageSpeed:分析网站速度和体验级数,提供优化建议。

    • GTmetrix:类似PageSpeed但报告更详细,也支持mobile测试。

    -黑灯瞎火:分析网站各项性能指标如图像大小、加载时间等。

    -图表分析工具:如DareBoost可以视觉化展示各项metrics变化趋势。

    -YSlow:检查网站按照Yahoo!的规则是否优化,定位坑点。

    -轻量级缓存:如Varnish缓存HTML提速访问。

    -数据库优化:正确索引、缓存查询等提升数据库性能。

    -图像优化:压缩图片尺寸、格式提升加载速度。

    -资源优化:合并JS/CSS、启用Gzip前端持续减少请求。

    -CDN:通过内容分发网络降低访问延迟。

    -异步任务:使用延迟队列处理低优先级任务。

    结合这些建议跟工具,能有效提升Magento网站的性能表现。定期监控也很关键。

    ]]>
    Sat, 16 Dec 2023 03:09:58 +0000
    <![CDATA[入门Magento主题开发需要掌握的技能]]> https://www.360magento.com/blog/skills-for-magento-theme-development/ 与网站前端设计息息相关的Magento主题开发是广大前端开发者常接触的一个领域。要想开发出高质量的Magento主题,开发者需要掌握一定的技能。本文将介绍入门Magento主题开发需要了解的一些基础知识。

    • HTML/CSS基础:了解网页结构标签和css样式规则。这是开发主题的基础。

    • 响应式设计:如何通过流式布局、媒体查询等手段开发出支持不同屏幕大小的响应式主题。

    • Less/Sass预处理器:使用变量、混合宏等特性高效开发主题样式表。

    • Magento模板系统:了解主题文件与模板的对应关系以及坐标查找规则。

    • 网格系统:Magento使用网格系统布局,需要掌握其工作原理。

    • 图片优化:如何优化图片尺寸和格式,减轻页面加载压力。

    • 主题自定义化:通过配置修改主题外观与功能,如更换logo颜色等。

    • PHP语法基础:需要处理少量PHP逻辑代码,如if条件判断。

    • 使用版本管理:使用Git等工具管理主题文件版本更新。

    掌握这些基础知识即可快速上手Magento主题开发。初期可以参考官方主题进行修改,并通过测试期迭代优化主题质量。掌握技巧后能自主设计主题。

    ]]>
    Fri, 15 Dec 2023 07:07:27 +0000
    <![CDATA[用模块化思想来优化你的Magento项目]]> https://www.360magento.com/blog/optimize-magento-project-with-modular-thinking/ 模块化开发已成为目前前端和后端开发中的主流思路。将完整项目拆分成各个完整的模块,可以有效提高代码可维护性和扩展能力。但是在Magento项目中,我们仍常见将所有代码集中在一个核心模块中。这就失去了模块化的诸多优点。

    所以要真正利用模块化思想优化Magento项目,需要遵循以下设计原则:

    1. 根据功能域划分模块边界,将一个大的需求区域抽象为一个独立的模块。

    2. 每个模块只负责自己的职责,对外提供明确的接口和契约。

    3. 模块间交互使用解耦的方式,如通过发布/订阅事件或基于接口编程。

    4. 各模块可以单独开发、测试和部署,不依赖其他模块的内部实现。

    5. 引用关系使用配置实现,如Composer,而不是硬编码。

    6. 提供完整的开发和运行环境以支持模块的快速迭代。

    将一个可复用的功能单元模块化实现后,我们可以灵活组合这些模块构建项目;代码可以每个小片段独立优化;将来也可以动态加载新模块扩展功能。这将带来开发效率和项目可维护性的很大提升。

    正确使用模块化思想是优化Magento项目的一个重要方面。希望这些经验可以给您的开发带来帮助。

    ]]>
    Fri, 15 Dec 2023 03:08:06 +0000
    <![CDATA[Magento 2: 提供客户体验的关键功能]]> https://www.360magento.com/blog/magento2-customer-experience/ 在竞争激烈的电子商务市场中,提供优质的客户体验是吸引和保留客户的关键。Magento 2作为一款功能强大的电子商务平台,提供了许多功能和工具,帮助您提供卓越的客户体验。在本篇博客中,我们将探讨Magento 2的关键功能,这些功能可以提升您的在线商店的客户体验,并分享一些最佳实践和技巧。

    1. 响应式和移动友好的设计:
      Magento 2提供了响应式设计,使您的在线商店能够自适应不同的设备和屏幕尺寸,包括桌面电脑、平板电脑和手机。移动友好的设计确保用户可以在任何设备上无缝浏览和购物,并提供一致的用户体验。

    2. 个性化内容和推荐:
      Magento 2允许您根据客户的兴趣、购买历史和行为数据,提供个性化的内容和推荐。通过使用Magento 2的营销工具和规则引擎,您可以向客户展示相关的产品、优惠和推广活动,提高购买转化率并增强客户满意度。

    3. 简化的购物流程:
      Magento 2的购物流程经过优化,使用户可以轻松浏览产品、添加到购物车、结账和支付。通过提供简化且直观的界面,减少步骤和点击次数,您可以提高购物的便捷性和顺畅性,从而增加销售机会。

    4. 多语言和多货币支持:
      如果您的在线商店面向国际客户,Magento 2提供了多语言和多货币支持。您可以轻松创建多个语言版本和货币设置,以满足不同地区和用户的需求,提供本地化的购物体验,增强全球客户的满意度。

    5. 顾客自助服务:
      Magento 2的自助服务功能允许客户进行自主管理,如查看订单状态、修改个人信息、申请退款等。通过提供自助服务,您可以减轻客户支持负担,提供便利和灵活性,增强客户对您品牌的忠诚度。

    结论:
    Magento 2的关键功能帮助您提供卓越的客户体验,从而增加客户满意度、提高销售转化率并促进业务增长。通过响应式设计、个性化内容和推荐、简化的购物流程、多语言和多货币支持以及顾客自助服务,您可以满足用户的期望,并建立良好的品牌形象。

    ]]>
    Thu, 14 Dec 2023 08:14:59 +0000
    <![CDATA[Magento 2: 提高销售和营销的关键策略]]> https://www.360magento.com/blog/magento2-sales-marketing/ 在竞争激烈的电子商务市场中,提高销售和营销的效果对于在线商店的成功至关重要。Magento 2作为一款强大的电子商务平台,提供了多种功能和策略,帮助您增加销售额并改进营销活动的效果。在本篇博客中,我们将探讨Magento 2的关键策略,以提高您的在线商店的销售和营销成果,并分享一些最佳实践。

    1. 促销和特价活动:
      Magento 2提供了丰富的促销和特价活动功能,使您能够轻松创建各种促销策略,如折扣码、团购、限时特价等。通过运用这些策略,您可以吸引客户,促进购买决策,并增加销售额。

    2. 奖励计划和积分系统:
      Magento 2允许您设置奖励计划和积分系统,以激励和回馈忠诚的客户。通过给予积分、折扣券或兑换礼品等奖励,您可以鼓励客户的重复购买行为,并建立长期客户关系。

    3. 个性化营销:
      利用Magento 2的个性化营销功能,您可以根据客户的行为、喜好和购买历史,发送定制化的营销内容和推荐。通过向客户提供个性化的体验,您可以增加购买转化率,并提高客户满意度和忠诚度。

    4. 购物车和结账优化:
      优化购物车和结账流程对于提高销售转化率至关重要。Magento 2提供了简化和优化的购物车和结账界面,使用户能够轻松添加商品、查看订单总结和进行安全快速的支付。通过提供顺畅的购物体验,您可以减少购物车遗弃率并促进完成订单。

    5. 数据驱动的决策:
      Magento 2的报告和分析功能提供了关键的业务数据和指标,帮助您了解销售趋势、顾客行为和营销活动的效果。通过基于数据做出决策,您可以优化产品定位、调整价格策略,并改进营销活动,以达到更好的销售和营销结果。

    结论:
    Magento 2的关键策略可以帮助您提高销售额并改进营销活动的效果。通过运用促销和特价活动、奖励计划和积分系统、个性化营销、购物车和结账优化以及数据驱动的决策,您可以吸引客户、促进购买决策,并提升客户满意度和忠诚度。

    ]]>
    Thu, 14 Dec 2023 03:16:40 +0000
    <![CDATA[Magento 2:提升电商运营效率的关键]]> https://www.360magento.com/blog/magento2-ecommerce-efficiency/ 在竞争激烈的电子商务市场中,高效运营是一个成功在线商店的关键要素。Magento 2作为一款功能强大的电子商务平台,提供了许多工具和功能,可以显著提升您的电商运营效率。在本篇博客中,我们将探讨Magento 2如何成为提升电商运营效率的关键,并分享一些最佳实践和技巧。

    1. 自动化流程:
      Magento 2允许您自动化许多重复性任务和流程,从而节省时间和减少错误。您可以设置自动化库存管理、订单处理、发货通知等功能,以提高处理效率并提供更快的客户服务。此外,Magento 2还提供了自动化报表和分析工具,帮助您快速了解业务绩效并做出相应的决策。

    2. 强大的管理工具:
      Magento 2提供了直观且易于使用的后台管理界面,使您能够轻松管理产品、库存、订单和客户等关键业务数据。您可以快速添加和编辑产品信息、创建和跟踪订单、管理客户信息,并进行灵活的报价和促销活动。这些管理工具帮助您更高效地处理日常任务,提高运营效率。

    3. 广泛的集成能力:
      Magento 2支持与第三方系统和服务的集成,如支付网关、物流服务、CRM系统等。通过集成这些关键系统,您可以实现数据的自动同步和流程的无缝连接,从而提高工作效率和减少人工干预。Magento 2的开放式API和扩展点使得集成变得更加简便和灵活。

    4. 多店铺管理:
      对于企业经营多个在线商店的情况,Magento 2提供了多店铺管理功能。您可以在单个Magento 2安装中运行多个商店,并共享产品目录、客户数据库和订单管理系统。这样,您可以通过一个统一的后台管理界面轻松管理多个商店,提高运营效率并降低维护成本。

    5. 数据驱动的决策:
      Magento 2提供了丰富的报表和分析功能,帮助您深入了解销售趋势、客户行为和产品表现。通过对这些数据的分析,您可以做出明智的决策和战略规划,以优化运营效率并提高业绩。Magento 2还支持与Google Analytics等第三方分析工具的集成,让您能够更全面地了解您的在线商店。

    结论:
    Magento 2是一个提升电商运营效率的强大工具。通过自动化流程、强大的管理工具、广泛的集成能力、多店铺管理和数据驱动的决策,Magento 2帮助企业更高效地管理和运营在线商店。无论是小型企业还是大型企业,Magento 2都能满足其不断增长的业务需求,并提供卓越的运营效率。

    ]]>
    Wed, 13 Dec 2023 08:11:11 +0000
    <![CDATA[ Magento 2的安全性与风险管理]]> https://www.360magento.com/blog/magento2-security1/ 在当今数字化时代,保护在线商店和客户的安全成为了至关重要的任务。作为一款广泛使用的电子商务平台,Magento 2注重安全性,并提供了一系列功能和最佳实践来帮助您管理安全风险。在本篇博客中,我们将探讨Magento 2的安全性与风险管理,并分享一些保护您的在线商店的关键措施。

    1. 安全更新和补丁:
      Magento 2定期发布安全更新和补丁,修复已知漏洞和弱点。及时安装这些更新是保护您的在线商店的重要步骤。Magento 2的后台管理界面提供了方便的升级和安装工具,使您能够轻松获取最新的安全修复程序。

    2. SSL加密:
      Magento 2支持SSL加密技术,通过为数据传输提供安全通道来保护敏感信息。使用有效的SSL证书可以确保客户的个人数据、支付信息和登录凭据得到加密,并防止被非法获取。启用SSL加密可提高您的在线商店的安全性,并增强客户对您的信任。

    3. 访问控制和身份验证:
      Magento 2提供了强大的访问控制和身份验证功能,以保护管理员和用户账户的安全。您可以设置复杂的密码策略、多因素身份验证和限制登录尝试次数等措施,减少未经授权的访问和潜在的安全风险。

    4. PCI DSS合规性:
      Magento 2符合PCI DSS(Payment Card Industry Data Security Standard)标准,这是一套涵盖支付卡数据安全的全球性标准。通过使用Magento 2与符合PCI DSS标准的支付网关集成,您可以确保客户的支付信息得到保护,并遵守相关的合规要求。

    5. 安全审计和监控:
      Magento 2提供了日志记录、事件监控和异常检测等功能,以帮助您跟踪和分析潜在的安全问题。通过监控登录活动、异常请求和系统日志,您可以及时发现和应对安全威胁,并采取适当的措施来保护您的在线商店。

    结论:
    Magento 2的安全性与风险管理功能使得保护您的在线商店和客户变得更加可靠和高效。通过及时安装安全更新、使用SSL加密、实施访问控制和身份验证、遵守PCI DSS合规性要求,并进行安全审计和监控,您可以降低安全风险,保护您的在线业务和客户数据。

    ]]>
    Wed, 13 Dec 2023 03:13:02 +0000
    <![CDATA[Magento 2:强大而灵活的电子商务平台]]> https://www.360magento.com/blog/magento-saa-dev-safsmasla/ Magento是目前最受欢迎的开源电子商务平台之一,提供了丰富的功能和灵活性,使商家能够轻松创建和管理在线商店。在本篇博客中,我们将介绍Magento 2的一些关键功能和技术优势,以及为什么它是许多企业选择的首选电子商务解决方案。

    1. 强大的功能套件:
      Magento 2提供了一整套功能,包括目录管理、产品管理、订单管理、支付和结账、客户管理、营销工具等。无论是小型企业还是大型企业,都可以根据其需求自定义和配置这些功能,以满足其特定的电子商务需求。

    2. 可扩展的架构:
      Magento 2采用了现代化的模块化架构,使开发人员能够轻松扩展和定制平台。它提供了丰富的API和扩展点,使开发人员可以根据需要添加新功能、集成第三方系统和服务,并优化性能。

    3. 强大的性能和可伸缩性:
      Magento 2通过使用Varnish缓存、数据库优化、页面片段缓存和延迟加载等技术,提供了卓越的性能。它还支持多服务器部署和负载均衡,以实现高可用性和可伸缩性,确保您的在线商店能够处理高流量和快速增长。

    4. 多店铺和多语言支持:
      Magento 2允许您在单个安装中运行多个在线商店,并为每个商店设置不同的产品目录、价格、支付选项和运费规则。此外,它还提供了多语言支持,使您能够轻松创建多语言版本的商店,以满足全球客户的需求。

    5. 丰富的市场和社区生态系统:
      Magento拥有庞大的市场和社区生态系统,提供了各种主题、模板、插件和扩展,以满足不同行业和业务需求。从设计到支付网关,从物流到营销自动化,您可以在Magento市场上找到适合您的解决方案。

    总结起来,Magento 2是一款功能强大、灵活可扩展的电子商务平台,适用于各种规模和类型的企业。它具有丰富的功能、可定制性强、性能优越,并拥有庞大的市场和社区支持。如果您正在寻找一个可靠的电子商务解决方案,Magento 2值得您的考虑

    ]]>
    Tue, 12 Dec 2023 08:02:30 +0000
    <![CDATA[使用Magento 2构建出色的电子商务体验]]> https://www.360magento.com/blog/magento2-ecommerce-experience/ 在当今数字化时代,电子商务已经成为许多企业成功的关键。为了在竞争激烈的市场中脱颖而出,选择一个功能强大、灵活且可定制的电子商务平台至关重要。在本篇博客中,我们将探讨如何使用Magento 2构建出色的电子商务体验,并为您提供一些最佳实践和技巧。

    1. 定制化能力:
      Magento 2是一款高度可定制的电子商务平台,可以满足各种业务需求。从产品目录和定价策略到支付和结账流程,您可以根据您的品牌和目标受众来定制和配置每个细节。利用Magento 2的灵活性,您可以为您的客户提供独特而个性化的购物体验。

    2. 响应式设计:
      移动设备的普及使得移动购物成为一种趋势。Magento 2提供了响应式设计的主题和布局,确保您的在线商店在各种设备上都能提供一致且优秀的用户体验。通过优化移动界面和用户导航,您可以提高移动用户的参与度和转化率。

    3. 强大的营销工具:
      Magento 2提供了丰富的营销工具,帮助您吸引潜在客户并提高销售额。您可以通过设置促销活动、优惠券和购物车价格规则来诱导购买行为。此外,Magento 2还具备强大的SEO功能,帮助您优化网站内容,提高搜索引擎排名。

    4. 高性能和可扩展性:
      Magento 2通过使用高级缓存技术、数据库优化和延迟加载等功能,提供卓越的性能。此外,它支持多服务器部署和负载均衡,保证您的在线商店能够处理高流量和快速增长。无论您的业务规模如何,Magento 2都能轻松应对。

    5. 安全性和可靠性:
      Magento 2以安全性为重点,提供多层次的安全措施来保护您和客户的数据。它支持符合PCI DSS标准的支付网关,并提供强大的身份验证和访问控制。此外,Magento 2还提供了可靠的备份和恢复功能,保障您的业务连续运行。

    结论:
    Magento 2是一个强大而灵活的电子商务平台,为企业提供了构建出色电子商务体验的工具和功能。定制化能力、响应式设计、强大的营销工具、高性能和可扩展性,以及安全性和可靠性,使得Magento 2成为许多企业的首选平台。通过利用Magento 2的优势,您可以建立一个引人注目且成功的在线商店

    ]]>
    Tue, 12 Dec 2023 03:10:19 +0000
    <![CDATA[Magento 电子商务:提升销售的战略和工具]]> https://www.360magento.com/blog/magento-ecommerce-sales-strategies/ Magento作为一款强大的电子商务平台,提供了多种战略和工具,可帮助企业提升销售业绩。在这篇文章中,我们将深入研究一些Magento电子商务的关键战略和工具,以助力你的在线业务取得更大的成功。

    1. 个性化用户体验

    通过Magento的个性化功能,你可以根据用户的历史购买记录、浏览行为和个人喜好,为他们呈现定制化的内容和推荐产品。这有助于提高购物体验,增加转化率。

    2. 强大的促销和优惠工具

    Magento提供丰富的促销和优惠工具,如限时促销、购物车规则和优惠券。合理运用这些工具可以刺激销售,吸引更多顾客完成购买。

    3. 全渠道销售整合

    整合线上线下销售渠道,创造一致的购物体验。Magento支持多个销售渠道的管理,使你能够更好地满足多样化的客户需求。

    4. 移动优化与响应式设计

    通过Magento的响应式设计,确保你的在线商店在各种移动设备上都能够提供优秀的用户体验。移动优化对于现代消费者至关重要,有助于提高销售。

    5. 实时库存管理

    保持实时库存追踪,避免因库存不足而失去销售机会。Magento的库存管理工具可以帮助你及时了解库存情况,制定合理的补货策略。

    6. 社交媒体整合

    整合社交媒体渠道,通过Magento的社交媒体整合工具将产品直接推送到各大平台。这有助于提高品牌知名度,吸引更多目标受众。

    ]]>
    Mon, 11 Dec 2023 07:41:46 +0000
    <![CDATA[Magento 2 营销大全:提升销售、拓展市场份额]]> https://www.360magento.com/blog/magento-2-marketing-strategies/ Magento 2作为一款强大的电子商务平台,提供了丰富的营销工具,帮助你提升销售、拓展市场份额。在本文中,我们将深入研究一些Magento 2的营销策略,助你在激烈的市场竞争中脱颖而出。

    1. 优化搜索引擎排名(SEO)

    通过Magento 2的SEO工具,优化产品页面、元标签和网站结构,提高在搜索引擎中的排名。这有助于增加有机流量,提高网站曝光度。

    2. 电子邮件营销

    建立强大的电子邮件营销策略,包括定期发送营销邮件、促销活动和新产品通知。通过Magento 2的电子邮件营销工具,保持与客户的紧密联系。

    3. 社交媒体推广

    整合社交媒体推广,通过Magento 2的社交媒体整合工具分享产品信息、促销活动,增加品牌曝光度。与潜在客户建立更紧密的联系。

    4. 积分与奖励计划

    建立积分与奖励计划,激励客户进行购物并参与其他活动。通过Magento 2的积分系统,提高用户忠诚度,增加重复购买率。

    5. 合作与联盟营销

    与其他品牌或业务建立合作与联盟关系,共同进行营销活动。通过Magento 2的合作伙伴管理,实施有效的联合营销计划。

    6. 满减与促销活动

    定期进行满减和促销活动,通过Magento 2的促销工具设置吸引人的优惠,促进销售增长。这可以提高购物车价值和客户满意度。

    结论

    通过这些Magento 2的营销策略,你可以在激烈的市场竞争中脱颖而出,提升销售业绩。精心设计的营销计划将有助于吸引新客户、保留现有客户,并在竞争激烈的市场中保持竞争力。

    ]]>
    Mon, 11 Dec 2023 03:00:00 +0000
    <![CDATA[Magento 2 进阶性能优化:提升网站速度与用户满意度]]> https://www.360magento.com/blog/magento-2-advanced-performance-optimization-s2/ Magento 2的进阶性能优化是提高网站速度和用户满意度的关键步骤。通过深入优化技术和实施高级策略,你可以为用户提供更快速、更流畅的购物体验。在本文中,我们将探讨一些Magento 2的高级性能优化策略,以帮助你实现网站速度的巅峰状态。

    1. 精细化代码优化

    进行更深入的代码优化,包括删除冗余代码、减少数据库查询次数和优化算法。通过审查代码,找到性能瓶颈并进行改进,提高系统响应速度。

    2. 高级缓存策略

    实施更高级的缓存策略,如Full Page Cache(FPC)和Object Caching。这些策略可以大幅度减少服务器响应时间,提升网站性能。

    3. 无限滚动与异步加载

    引入无限滚动和异步加载技术,以减少页面的加载次数。通过仅在需要时加载内容,提高用户体验,减轻服务器负担。

    4. 前端资源优化

    精细化前端资源的加载,包括压缩CSS和JavaScript文件、延迟加载和最小化HTTP请求。这有助于减少页面加载时间,改善用户感知。

    5. 自动化任务调度

    使用任务调度系统自动化任务,如数据清理、索引重建等。通过将这些任务放入后台进行处理,避免阻塞前台操作,提高网站的即时响应性。

    6. 高级性能监控和分析

    引入高级性能监控和分析工具,以实时追踪性能指标、错误率和用户行为。通过深入分析,及时发现潜在问题并采取相应措施。

    结论

    通过实施这些高级性能优化策略,你将能够将Magento 2网站的性能提升到一个全新的水平。这不仅将满足用户的高期望,同时也将有助于提高搜索引擎排名和用户满意度。

    ]]>
    Sun, 10 Dec 2023 07:10:00 +0000
    <![CDATA[Magento 2进阶性能优化:更高速、更出色的电商体验]]> https://www.360magento.com/blog/magento-2-advanced-performance-optimization/ Magento 2的性能优化是一个不断演进的过程,通过更进一步的优化策略,可以进一步提升网站速度,提供更出色的电商体验。在本文中,我们将深入研究一些Magento 2的进阶性能优化策略,帮助你实现更高速、更卓越的网站性能。

    1. 使用缓存层

    在Magento 2上使用额外的缓存层,如Varnish或Redis,以加速页面交付。这样可以减轻服务器负担,提高响应速度。

    2. 优化数据库查询

    深入优化Magento 2的数据库查询,使用索引、合理的查询语句,以确保数据库操作的效率。定期清理无用的数据,保持数据库的轻量级。

    3. 服务端优化

    优化服务器设置,包括Web服务器(如Nginx或Apache)和数据库服务器。调整服务器参数,增加硬件资源,以适应不断增长的访问量。

    4. 使用异步任务

    将一些耗时的任务转换为异步任务,如图片处理、邮件发送等。这样可以避免阻塞主要操作,提高页面加载速度。

    5. 定期监控和调整

    使用监控工具,定期检查网站性能。根据监控结果,调整配置、优化代码,以适应不断变化的需求和流量。

    6. 内容优化和CDN进阶应用

    进一步优化网站内容,确保高质量的内容交付。将CDN的应用进一步优化,选择更适合你网站的CDN服务商,提供更广泛的内容分发。

    结论

    通过这些进阶性能优化策略,你可以将Magento 2网站的性能提升到一个新的水平。这将不仅为用户提供更出色的体验,同时也为你的电商业务的成功打下坚实的基础。

    ]]>
    Sun, 10 Dec 2023 03:27:55 +0000
    <![CDATA[Magento 2安全性策略:保护商店和客户的隐私安全]]> https://www.360magento.com/blog/magento-Security-policy/ Magento 2作为一款广受欢迎的电子商务平台,安全性至关重要。保护商店和客户的隐私安全是维护声誉和业务持续发展的关键因素。在本文中,我们将深入研究一些Magento 2的安全性策略,以确保你的商店和客户信息的安全。

    1. 及时更新Magento 2

    保持Magento 2平台及其组件的更新非常重要。及时应用最新的补丁和安全更新,以防范潜在的漏洞和安全威胁。

    2. 强化管理员账户安全性

    确保管理员账户具有足够的安全性。使用强密码,并定期更改密码。限制管理员账户的访问权限,只允许必要的操作,以降低潜在威胁。

    3. 启用SSL加密

    使用SSL(安全套接层)加密来保护客户在网站上的敏感信息。确保在Magento 2中启用SSL,特别是在结账过程中,以加密付款信息等关键数据。

    4. 实施两步验证(2FA)

    在Magento 2中启用两步验证,增加对管理员和用户账户的额外层次的安全验证。这种额外的认证步骤有助于防止未经授权的访问。

    5. 监控日志和报警

    启用Magento 2的日志记录功能,并设置报警系统,以及时获得异常活动的通知。监控日志有助于及时发现潜在的安全问题,并采取必要的措施。

    6. 备份数据

    定期备份Magento 2的数据库和文件,确保在发生数据丢失或系统崩溃时能够快速恢复。存储备份文件在安全的位置,以防止未经授权的访问。

    结论

    通过严格执行这些Magento 2安全性策略,你可以有效地保护商店和客户的隐私安全。安全性是建立信任、确保商业连续性的关键环节,务必引起足够的重视。

    ]]>
    Sat, 09 Dec 2023 08:00:00 +0000
    <![CDATA[Magento 2性能优化策略:提升网站速度,优化用户体验]]> https://www.360magento.com/blog/magento-2-performance-optimization-s/ Magento 2作为一款功能丰富的电子商务平台,优化性能对于提供卓越的用户体验至关重要。在本文中,我们将深入研究一些Magento 2的性能优化策略,帮助你提升网站速度,优化用户体验。

    1. 启用页面缓存

    在Magento 2中启用页面缓存,以减少页面加载时间。缓存页面的静态内容,使用户在访问相同页面时能够更快地加载。

    2. 图片优化

    对产品图片进行优化,包括压缩图片和使用适当的图片格式。确保图片文件大小合理,以减少页面加载时间,提高性能。

    3. 延迟加载(Lazy Loading)

    使用延迟加载技术,使页面上的图片和其他资源在用户滚动到它们时才加载。这有助于加速初始页面加载时间,提升用户体验。

    4. 合并和压缩CSS和JavaScript文件

    合并和压缩Magento 2的CSS和JavaScript文件,减少文件大小,加快页面加载速度。这可以通过Magento 2的后台设置或使用优化工具实现。

    5. 使用CDN加速

    整合内容分发网络(CDN)以加速静态资源的加载。CDN可以将这些资源分发到全球多个服务器,使用户从最近的服务器加载资源,提高访问速度。

    6. 优化数据库

    定期优化Magento 2的数据库,删除无用的数据和日志。一个清理的数据库有助于提高数据库查询性能,加速页面加载。

    结论

    通过实施这些Magento 2性能优化策略,你可以显著提升网站速度,优化用户体验。快速加载的网站不仅有助于留住访问者,还对搜索引擎排名产生积极影响。

    ]]>
    Sat, 09 Dec 2023 03:26:03 +0000
    <![CDATA[Magento 2社交媒体整合与影响力营销:拓展品牌影响力,吸引更多客户]]> https://www.360magento.com/blog/magento-Social-media/ 1. 社交媒体账号整合

    整合Magento 2与你的社交媒体账号,包括Facebook、Instagram、Twitter等平台。确保产品页面、促销信息都能方便地分享到社交媒体,扩大品牌曝光。

    2. 社交分享和互动

    在Magento 2商店中添加社交分享按钮,鼓励用户分享他们的购物体验、喜欢的产品或促销信息。及时回复用户在社交媒体上的评论和提问,建立积极的互动关系。

    3. 社交媒体广告整合

    结合Magento 2的广告整合功能,将社交媒体广告与你的电商活动相结合。通过有针对性的社交广告,提高品牌知名度,引导潜在客户访问你的网站。

    4. 合作和赞助

    与有影响力的社交媒体用户、博主或其他品牌进行合作和赞助。这样的合作可以为你的品牌带来更广泛的关注,提高潜在客户的信任度。

    5. 创建有趣的社交媒体内容

    通过Magento 2的内容管理系统,创建有趣而有吸引力的社交媒体内容。这可以包括教程、产品展示、幕后故事等,以提升品牌故事性和用户互动性。

    6. 用户生成内容(UGC)活动

    鼓励用户生成内容,例如上传他们使用你产品的照片或分享使用心得。通过Magento 2的UGC活动,可以在社交媒体上展示这些内容,增强社区感和用户参与度。

    结论

    Magento 2的社交媒体整合和影响力营销工具可以帮助你更好地利用社交平台,与潜在客户建立连接,提高品牌影响力。通过巧妙整合社交媒体,你将能够在竞争激烈的市场中脱颖而出。

    ]]>
    Fri, 08 Dec 2023 07:21:05 +0000
    <![CDATA[Magento 2客户服务与忠诚度建设:创造卓越体验,促进长期关系]]> https://www.360magento.com/blog/magento-customer-service/ Magento 2作为一款综合性的电子商务平台,提供了丰富的客户服务和忠诚度建设工具,帮助你创造卓越的购物体验,促进客户忠诚度。在本文中,我们将深入研究一些Magento 2的客户服务和忠诚度建设策略,助力你在竞争激烈的市场中赢得客户的长期支持。

    1. 多渠道客服支持

    整合多渠道客服支持,包括在线聊天、电子邮件、电话等。确保客户可以轻松找到并选择最适合他们的联系方式,解决问题和提供支持。

    2. 实时在线聊天

    在Magento 2商店中添加实时在线聊天功能,使客户能够立即与客服代表互动。这有助于解决即时问题,提高购物体验。

    3. 积分和奖励计划

    建立积分和奖励计划,激励客户进行购物并参与其他活动。通过Magento 2的积分系统,为客户提供折扣、礼品或会员特权,增加他们的忠诚度。

    4. 个性化服务

    利用Magento 2的客户分析工具,了解客户的购物历史和偏好。基于这些信息,提供个性化的产品建议、促销和服务,使客户感到特别重视。

    5. 定期沟通和回馈

    建立定期沟通和反馈机制,通过电子邮件、短信或其他渠道与客户保持联系。向客户发送特别优惠、新产品信息,并鼓励他们提供反馈,以改善服务。

    6. 售后服务和保修政策

    明确的售后服务和保修政策是建立客户信任的重要因素。在Magento 2商店中清晰地展示售后服务政策,确保客户在购物后有可靠的支持。

    结论

    通过提供卓越的客户服务和实施忠诚度建设策略,你可以在Magento 2平台上建立长期关系,促进客户忠诚度。满足客户需求、提供个性化服务将帮助你在激烈的市场竞争中脱颖而出。

    ]]>
    Fri, 08 Dec 2023 03:22:06 +0000
    <![CDATA[Magento 2 Data analysis and marketing strateg:基于洞察力制定成功计划]]> https://www.360magento.com/blog/Magento-Data-analysis-and-marketing/ Magento 2作为一款全面的电子商务平台,提供了丰富的数据分析工具,帮助你更好地理解用户行为并制定有效的营销策略。在本文中,我们将深入研究一些Magento 2的数据分析和营销策略,以基于深入洞察力制定成功的电商计划。

    1. 使用Google Analytics整合

    整合Google Analytics到你的Magento 2商店,以获取全面的网站访问数据。通过分析用户行为、流量来源和转化率等指标,你可以更好地了解用户喜好和购物习惯,从而调整营销策略。

    2. 购物者流程分析

    使用Magento 2的购物者流程分析工具,深入了解用户在购物过程中的行为路径。确定用户在网站上的关键互动点,并优化这些步骤,以提高转化率和销售。

    3. 利用A/B测试

    进行A/B测试,测试不同的页面布局、促销活动或产品展示方式。通过比较不同变体的性能,你可以确定哪种设计或策略更有效,从而优化用户体验和提高转化率。

    4. 分析购物篮放弃率

    深入分析购物篮放弃率,找出用户在结账前放弃购物篮的原因。可能是高额的运费、繁琐的结账流程等问题。通过解决这些问题,可以提高结账完成率。

    5. 客户分群和个性化营销

    使用Magento 2的客户分群功能,将用户划分为不同的群体,根据其行为和偏好制定个性化的营销计划。通过向特定群体发送定制的促销信息,提高用户参与度和购买意愿。

    6. 实时销售和库存分析

    通过实时销售和库存分析,了解热门产品、畅销时段和库存水平。基于这些信息,可以调整库存管理、推动促销活动,并在高需求时提供更多库存。

    结论

    Magento 2提供了强大的数据分析工具,帮助你更好地理解用户行为和网站性能。通过深入洞察力,你可以制定更精准的营销策略,提高销售效果,促使业务的不断增长。

    ]]>
    Thu, 07 Dec 2023 07:20:03 +0000
    <![CDATA[Improve Magento 2 User experience (UX):创造令人难忘的购物旅程]]> https://www.360magento.com/blog/Improve-Magento-User-experience/ Magento 2作为一款强大的电子商务平台,注重用户体验至关重要。在本文中,我们将深入了解一些提升Magento 2用户体验的关键策略,以创造令人难忘的购物旅程,促进客户忠诚度和提高销售。

    1. 响应式设计

    确保你的Magento 2商店采用响应式设计,以确保在各种设备上都能提供一致而流畅的用户体验。无论是在台式电脑、平板还是手机上,用户都应该能够轻松访问和浏览你的网站。

    2. 简洁而直观的导航

    设计简洁而直观的导航结构,让用户能够轻松找到他们想要的产品。清晰的菜单、有效的筛选和搜索功能都是帮助用户快速导航的关键。

    3. 快速的页面加载速度

    优化Magento 2商店的页面加载速度,确保用户能够快速访问产品页面。压缩图像、启用浏览器缓存、减少HTTP请求等优化措施,都有助于提高页面加载速度。

    4. 个性化推荐和建议

    利用Magento 2的个性化推荐功能,向用户展示他们可能感兴趣的产品。根据用户的浏览历史、购买记录和个人喜好,定制推荐,提升购物体验。

    5. 简化结账流程

    简化Magento 2商店的结账流程,减少用户的购物车放弃率。优化每个结账步骤,提供明确的指导,尽量减少填写表单的步骤,让结账过程更加顺畅。

    6. 实时支持和反馈

    提供实时支持和反馈机制,确保用户在购物过程中能够得到及时的帮助。集成在线聊天、客服热线或提供详细的帮助文档,为用户提供全方位的支持。

    结论

    通过关注用户体验,你可以建立一个引人入胜的购物旅程,增加用户满意度和忠诚度。Magento 2提供了丰富的工具,帮助你优化用户体验,为用户创造难忘的购物体验

    ]]>
    Thu, 07 Dec 2023 03:03:00 +0000
    <![CDATA[Magento 2 e-commerce marketing strategy:吸引客户、提升销售]]> https://www.360magento.com/blog/Magento-2-e-commerce-marketing-strategy/ Magento 2作为一款强大的电子商务平台,提供了丰富的营销工具,帮助商家吸引客户、提高销售。在本文中,我们将深入探讨一些Magento 2的营销策略,让你更好地利用平台功能,打造成功的电商业务。

    1. 创建引人注目的产品页面

    首先,确保你的产品页面设计引人注目。清晰的产品图片、详细的产品描述以及明确的购买按钮都是关键因素。采用响应式设计,确保在各种设备上都能提供出色的用户体验。

    2. 优惠券和促销活动

    Magento 2提供了灵活的优惠券和促销活动功能。利用这些功能,制定吸引人的促销策略,如打折、满减、赠品等,以激发客户的购买欲望。定期举办促销活动,吸引新客户并保持现有客户的忠诚度。

    3. 电子邮件营销

    建立强大的电子邮件营销策略,与客户保持联系。Magento 2允许你轻松地发送订单确认、促销信息、新产品推介等电子邮件。利用个性化的邮件内容,提高打开率和转化率。

    4. 社交媒体整合

    将社交媒体整合到Magento 2中,以扩大你的品牌影响力。分享产品、举办社交媒体竞赛、与客户互动,都是有效的社交媒体策略。通过社交分享按钮,让客户方便地分享他们的购物体验。

    5. 客户评论和建议

    鼓励客户留下产品评论和建议,这有助于增强信任感。正面的评价和建议对于其他潜在客户的购物决策起到重要作用。及时回复客户的评论,显示关注和专业。

    6. 购物车提醒和放弃购物车恢复

    Magento 2允许你设置购物车提醒,提醒客户他们的购物车中尚有未结账的商品。同时,设置放弃购物车恢复策略,通过电子邮件或其他渠道引导客户完成购买。

    结论

    Magento 2提供了丰富的营销工具,帮助你吸引客户、提高销售。通过巧妙利用这些功能,你可以制定出成功的电商营销策略,提升品牌知名度并增加盈利。

    ]]>
    Wed, 06 Dec 2023 07:16:40 +0000
    <![CDATA[Magento 2搜索引擎优化(SEO)策略:提高在线商店可见性]]> https://www.360magento.com/blog/Magento-Search-Engine-Optimization/ Magento 2作为一款强大的电子商务平台,提供了丰富的搜索引擎优化(SEO)功能,帮助商家提高在线商店在搜索引擎中的可见性。在本文中,我们将深入了解一些Magento 2的SEO策略,让你的商店在搜索结果中脱颖而出。

    1. 优化产品页面标题和描述

    确保每个产品页面都有独特、吸引人的标题和描述。标题和描述是搜索引擎展示结果中的第一印象,因此要使它们既包含关键词,又能吸引用户点击。

    2. 友好的URL结构

    设置Magento 2的URL结构为友好的形式。清晰、简洁的URL不仅有助于搜索引擎理解页面内容,还提升用户体验。使用描述性词汇和关键词来构建URL。

    3. 关键词研究和使用

    进行关键词研究,了解潜在客户在搜索引擎中使用的关键词。在产品描述、页面标题、标签等位置巧妙地使用这些关键词,以提高页面在搜索结果中的排名。

    4. 创建XML网站地图

    Magento 2允许你创建XML网站地图,这有助于搜索引擎索引你的网站。确保地图包含所有重要的页面链接,并在网站根目录下提供sitemap.xml文件。

    5. 优化图片

    对产品图片进行优化,包括使用描述性文件名和ALT文本。优化后的图片有助于提高页面加载速度,同时也能在图像搜索结果中显示。

    6. 社交媒体整合

    整合社交媒体到你的Magento 2商店,通过社交分享和互动来增强在线商店的社交信号。社交信号对搜索引擎排名有一定影响,因此积极参与社交媒体是一项有效的SEO策略。

    结论

    Magento 2的SEO功能为优化在线商店提供了丰富的工具。通过合理利用这些功能,你可以提高商店在搜索引擎中的可见性,吸引更多潜在客户,并提升销售。

    ]]>
    Wed, 06 Dec 2023 03:17:44 +0000
    <![CDATA[深入了解Magento 2主题定制:打造独特的在线商店外观]]> https://www.360magento.com/blog/magento-stheme-customer/ Magento 2 是一款强大而灵活的电子商务平台,而主题定制是确保你的在线商店在外观上与众不同的关键步骤之一。在本文中,我们将探讨如何定制Magento 2主题,以便根据你的品牌和业务需求创建一个独特的用户体验。

    1. 了解Magento 2主题结构

    首先,理解Magento 2主题的结构是至关重要的。主题通常包括布局文件、模板文件、样式表和JavaScript文件。深入研究Magento 2主题结构将使你能够更有效地进行定制。

    2. 创建自定义主题

    Magento 2允许你创建自定义主题,以便轻松地进行定制。通过在app/design/frontend目录下创建你自己的主题,你可以开始定制你的商店的外观。确保你的主题从Magento 2的默认主题或其他现有主题继承,以便获取基本的样式和功能。

    3. 修改样式和布局

    通过修改主题的样式表和布局文件,你可以调整商店的颜色、字体、排列方式等。使用LESS或CSS预处理器,可以更轻松地管理样式。同时,Magento 2的布局文件允许你重新排列页面元素,以满足你的布局需求。

    4. 添加自定义图像和图标

    通过替换默认的图像和图标,可以将商店的外观与品牌形象相匹配。确保你的图像符合Magento 2的建议尺寸和规范,以确保页面加载速度和用户体验。

    5. 集成自定义JavaScript

    如果你需要添加特定的交互性或功能,可以通过集成自定义JavaScript来实现。例如,实现产品页面上的动画效果或改进购物车的交互性。

    结论

    通过深入了解Magento 2主题定制,你可以打造一个独特、引人注目的在线商店外观,与众不同地展示你的品牌。通过合理使用Magento 2的主题定制功能,你将能够为你的客户提供一个独特而难忘的购物体验。

    ]]>
    Tue, 05 Dec 2023 07:13:15 +0000
    <![CDATA[提升Magento 2安全性:保护你的在线商店和客户信息]]> https://www.360magento.com/blog/magento2-Improved/ Magento 2是一款功能丰富的电子商务平台,而安全性是确保商店和客户信息安全的至关重要的方面。在本文中,我们将深入探讨一些提升Magento 2安全性的关键步骤,以确保你的电子商务运营得到充分的保护。

    1. 及时更新Magento 2

    始终保持Magento 2的更新是确保安全性的基本步骤。Magento的更新通常包括对潜在漏洞的修复和增强安全性的改进。定期检查并应用最新的Magento 2版本,以确保你的商店处于最安全的状态。

    2. 使用SSL加密

    使用SSL(安全套接层)加密是保护客户信息不被窃取的重要手段。确保在Magento 2中启用SSL,以加密数据传输,包括用户登录信息、付款详情等。购物车和结账过程中使用SSL是至关重要的。

    3. 强化管理员账户安全

    采取措施确保管理员账户的强大安全性是至关重要的。使用强密码,并定期更改密码。另外,限制管理员账户的访问权限,只允许必要的操作。

    4. 监控日志和报警

    启用Magento 2的日志记录功能,并设置报警系统,以便在发生异常活动时及时获得通知。通过监控日志,你可以及时发现潜在的安全威胁,并采取必要的措施。

    5. 防火墙和安全插件

    考虑在Magento 2中使用防火墙和安全插件,以提供额外的保护层。这些工具可以帮助检测和阻止潜在的恶意活动,增加商店的整体安全性。

    6. 定期备份

    定期备份Magento 2的数据库和文件是一种防范措施,可以在发生数据丢失或系统崩溃时快速恢复。确保备份是可用的,并存储在安全的位置。

    结论

    通过采取这些关键步骤,你可以显著提升Magento 2商店的安全性,保护客户信息免受潜在威胁。安全性是电子商务成功运营的基石,因此投资于Magento 2的安全性绝对是值得的。

    ]]>
    Tue, 05 Dec 2023 03:15:14 +0000
    <![CDATA[深入了解Magento 2:强大的电子商务平台]]> https://www.360magento.com/blog/about-magento-shop/ Magento 2 是一款领先的开源电子商务平台,为在线商店提供了出色的灵活性和功能。在本文中,我们将深入探讨Magento 2的一些主要功能和优势。

    1. 现代化的架构

    Magento 2采用了现代化的架构,利用了最新的技术和最佳实践。这包括使用PHP 7和HTML5等技术,为用户提供更快、更可靠的购物体验。

    2. 响应式设计

    随着移动设备的普及,响应式设计变得至关重要。Magento 2通过提供响应式主题确保你的在线商店在各种设备上都能够提供优质的用户体验,从而提高销售和客户满意度。

    3. 强大的扩展性

    Magento 2提供了丰富的扩展性,允许你通过安装插件和扩展来定制和扩展你的商店功能。这使得Magento 2成为适应不同业务需求的理想选择。

    4. 全球化支持

    对于国际业务而言,Magento 2提供了多语言和多货币支持,使你的商店能够轻松扩展到全球市场。同时,它还支持不同的税收和运费规则,以适应不同的地理位置。

    5. 先进的安全性

    Magento 2致力于保护你的在线业务免受潜在威胁。通过使用SSL加密、安全支付网关和数据备份等功能,Magento 2确保你的商店和客户数据得到充分的保护。

    结论

    Magento 2是一款功能强大、灵活且现代的电子商务平台,适用于各种规模的企业。无论你是刚刚起步还是已经运营多年的企业,Magento 2都能提供所需的工具和功能,帮助你建立成功的在线业务。

    ]]>
    Mon, 04 Dec 2023 07:11:34 +0000
    <![CDATA[深入了解Magento 2扩展开发:为你的在线商店增加定制功能]]> https://www.360magento.com/blog/magento-dev-enline-shop/ Magento 2是一款功能强大的电子商务平台,而通过扩展开发,你可以为你的在线商店增加各种定制功能,以满足特定业务需求。在本文中,我们将深入了解Magento 2扩展开发的基础知识,帮助你打造一个更强大、更灵活的电子商务解决方案。

    1. 创建自定义Magento 2扩展

    首先,了解如何创建自定义Magento 2扩展是至关重要的。通过在app/code目录下创建自己的扩展,你可以开始为商店添加新功能。确保你的扩展结构符合Magento 2的标准,以便顺利运行。

    2. 了解Magento 2扩展的结构

    了解Magento 2扩展的结构将有助于更好地组织和管理你的代码。Magento 2扩展通常包括控制器、模型、观察者和布局文件等元素。深入了解这些组件将有助于你更好地理解扩展的工作原理。

    3. 创建自定义控制器和模型

    通过创建自定义控制器和模型,你可以在Magento 2中添加新的业务逻辑。这使你能够处理特定的请求、生成自定义数据或与数据库交互。确保你的控制器和模型遵循Magento 2的最佳实践,以确保性能和稳定性。

    4. 使用观察者添加事件

    Magento 2的事件和观察者模式允许你在系统中添加自定义事件,并在需要时执行相应的操作。通过创建观察者,你可以在Magento 2中捕获特定的事件,并在事件发生时执行自定义代码,以实现更高度定制化的功能。

    5. 布局文件和前端资产

    通过创建自定义布局文件,你可以更改页面的结构和元素排列。同时,通过添加前端资产,如JavaScript和CSS文件,可以改进用户界面的外观和交互性。

    结论

    通过深入了解Magento 2扩展开发,你可以为你的在线商店添加各种自定义功能,从而提升用户体验并满足特定业务需求。合理利用Magento 2的扩展开发功能,将使你的电子商务解决方案更具竞争力。

    ]]>
    Mon, 04 Dec 2023 04:14:16 +0000
    <![CDATA[Magento 2 移动应用开发与响应式设计]]> https://www.360magento.com/blog/magento2-mobile-app-development-responsive-design/ 在当今数字化时代,移动设备的普及使得移动应用开发和响应式设计成为电子商务领域的重要趋势之一。对于使用 Magento 2 的电商网站,开发移动应用以及实施响应式设计可以为用户提供更好的移动体验,增强用户参与度和提升销售业绩。本篇博文将介绍 Magento 2 移动应用开发和响应式设计的关键要点。

    移动应用开发:

    1. 选择适当的移动应用开发框架:Magento 2 提供了 REST API,使得开发人员能够构建自定义的移动应用。您可以选择流行的移动应用开发框架,如 React Native、Flutter 或 Ionic,来构建跨平台的移动应用。

    2. 集成 Magento 2 API:使用 Magento 2 的 REST API,您可以在移动应用中访问和管理产品、订单、客户等数据。确保使用安全的认证方式,以保护敏感数据。

    3. 优化移动应用性能:移动应用的性能对于用户体验至关重要。优化应用的加载速度、响应时间和资源管理,以确保流畅的用户体验。

    4. 设计用户友好的界面:在移动应用中,设计简洁、直观且易于操作的用户界面非常重要。遵循移动应用设计准则,并确保应用的布局和导航在不同屏幕尺寸上都能良好地适应。

    响应式设计:

    1. 使用响应式主题:Magento 2 提供了多个响应式主题,可以根据不同设备的屏幕尺寸和分辨率来自动调整布局和样式。选择适合您品牌形象和用户体验的主题,并进行必要的定制。

    2. 图片优化:针对移动设备,优化网站中的图片以减少加载时间。使用适当的图像压缩和缩放技术,确保在保持良好视觉质量的同时减小文件大小。

    3. 响应式导航和交互元素:设计导航和交互元素,以便在不同设备上易于触摸和操作。使用移动友好的菜单和按钮样式,确保用户能够轻松导航和与网站进行交互。

    4. 跨浏览器和设备测试:在实施响应式设计之前,进行广泛的测试,以确保您的网站在各种浏览器和设备上都能提供一致的用户体验。

    通过在 Magento 2 上进行移动应用开发和响应式设计,您可以为用户提供无缝的移动体验,并达到更高的用户满意度和销售转化率。

    ]]>
    Sun, 03 Dec 2023 07:44:40 +0000
    <![CDATA[了解Magento布局:构建强大的电子商务网站]]> https://www.360magento.com/blog/understanding-magento-layout-building-powerful-ecommerce-website/ Magento是一个功能强大的电子商务平台,它提供了灵活的布局系统,使您能够构建定制化和响应式的电子商务网站。在本文中,我们将深入了解Magento的布局系统,了解它的工作原理以及如何利用它来构建强大的电子商务网站。

    什么是Magento布局?

    Magento布局是指定义和组织页面结构的XML文件。它决定了页面中各个元素的位置、顺序和外观。布局文件位于Magento主题的app/design/frontend/{Vendor}/{Theme}/Magento_Theme/layout目录下,其中{Vendor}{Theme}是您当前使用的主题的名称。

    布局文件的结构

    Magento布局文件由一个或多个XML文件组成。其中最重要的文件是default.xml,它定义了网站的默认布局。其他布局文件可以覆盖和扩展默认布局,以适应不同的页面和区域。

    布局文件通常包含以下几个主要部分:

    1. <layout> 根元素:它是布局文件的根元素,包含所有其他元素。
    2. <head> 元素:它定义了页面的头部部分,通常用于引入CSS和JavaScript文件。
    3. <body> 元素:它定义了页面的主体部分,包含各个区块和容器。
    4. <referenceContainer> 元素:它用于定义和配置容器,容器将包含其他区块。
    5. <block> 元素:它用于定义和配置区块,区块是页面上的可重用组件,例如导航栏、产品列表等。
    6. <referenceBlock> 元素:它用于引用和配置已定义的区块,并进行进一步的配置或修改。
    7. <referenceContainer> 和 <referenceBlock> 元素也可以包含其他元素,以实现更高级的布局操作。

    使用Magento布局构建网站

    通过使用Magento布局,您可以根据需要自定义和调整页面的结构和外观。以下是一些在构建Magento网站时使用布局的常见场景和操作:

    1. 添加、移除或修改区块(Blocks):使用 <referenceBlock> 元素可以引用已定义的区块,并进行进一步的配置或修改。您可以修改区块的属性、位置和样式,或者添加新的区块来扩展页面功能。

    2. 调整容器(Containers):使用 <referenceContainer> 元素可以引用已定义的容器,并进行进一步的配置或修改。您可以通过添加、移除或重新排序容器中的区块来调整页面的布局和结构。

    3. 扩展和重写布局文件:您可以创建自定义的布局文件,并将其放置在主题目录中,以覆盖或扩展默认布局文件。这使您能够根据需要自定义特定页面或区域的布局。

    4. 响应式布局:Magento提供了响应式设计的支持,使您可以根据不同的设备和屏幕尺寸调整页面的布局和外观。通过使用CSS媒体查询和Magento的响应式类,您可以为不同的设备提供定制的布局和样式。

    总结

    Magento的布局系统为构建强大的电子商务网站提供了灵活而强大的工具。通过了解Magento布局文件的结构和使用方法,您可以根据需要自定义和调整页面的结构、布局和外观。使用Magento的布局系统可以创建灵活且独特的电子商务网站,为用户提供出色的购物体验。

    ]]>
    Sun, 03 Dec 2023 03:06:44 +0000
    <![CDATA[Magento 2性能优化和缓存管理:加速您的电子商务网站]]> https://www.360magento.com/blog/magento-2-performance-optimization-and-cache-management/
  • 理解Magento 2性能瓶颈
  • 首先,我们需要了解Magento 2可能面临的性能瓶颈。这些包括数据库查询、代码优化、资源加载、HTTP请求和响应时间等。通过识别和解决这些瓶颈,您可以显著提高网站的性能。

    1. Magento 2缓存机制

    Magento 2提供了多种缓存机制来加速网站加载速度。了解Magento 2的缓存类型,如页面缓存、块缓存、配置缓存等,以及如何启用、配置和清除缓存,是优化性能的关键。

    1. 优化策略和技巧

    在Magento 2中,有许多优化策略和技巧可帮助您提升网站性能。这些包括使用CDN(内容分发网络)、压缩和合并CSS和JavaScript文件、优化图像、启用代码缓存和自动优化、使用高性能服务器和数据库等。了解这些策略并实施它们,将显著改善网站的性能。

    1. 工具和技术

    在优化Magento 2性能时,有一些有用的工具和技术可帮助您监测和分析性能瓶颈。这些工具包括Magento自带的性能配置、第三方性能分析工具(如New Relic、Blackfire等)、代码审查工具和调试工具。通过使用这些工具,您可以获得关于性能瓶颈的详细信息,并采取相应的措施来解决它们。

    总结:

    本篇博文提供了关于Magento 2性能优化和缓存管理的指导和技巧,帮助您加速和提升电子商务网站的性能。通过理解Magento 2的性能瓶颈、缓存机制、优化策略以及使用相关工具和技术,您将能够实现更快、更高效的网站加载和响应速度。

    ]]>
    Sat, 02 Dec 2023 07:51:52 +0000
    <![CDATA[Magento 2多语言和多货币支持:扩展您的电子商务业务]]> https://www.360magento.com/blog/magento-2-multilingual-multicurrency-support/
  • 多语言设置
  • 了解Magento 2的多语言设置是实现多语言支持的第一步。Magento 2提供了多语言包,您可以选择适合您目标市场的语言包进行安装和配置。同时,了解如何管理翻译文件、启用和禁用语言、处理静态文本和动态内容,将帮助您实现网站的多语言支持。

    1. 翻译和本地化

    为了确保网站内容的准确翻译和本地化,您可以使用Magento 2的翻译工具或第三方翻译服务。这包括对产品描述、页面文本、导航菜单、错误消息等的本地化处理。通过提供本地化的内容,您能够更好地满足不同语言用户的需求。

    1. 多货币配置

    Magento 2还提供了多货币配置功能,使您能够根据不同市场的需求设置不同的货币。您可以配置货币符号、汇率转换、税收设置等,以确保正确显示和计算不同货币的价格。这将帮助您吸引全球客户并提高销售效益。

    1. 扩展和技巧

    Magento 2的市场上有许多扩展和技巧可帮助您更好地实现多语言和多货币支持。这些扩展包括多语言翻译扩展、货币切换扩展、自动地理定位扩展等。了解这些扩展和技巧,并根据您的需求选择适合的解决方案,将为您的电子商务业务带来便利和优势。

    总结:

    本篇博文介绍了Magento 2多语言和多货币支持的重要性,并提供了实现这些功能的指导和建议。通过正确配置多语言设置、翻译和本地化处理、多货币配置以及应用相关的扩展和技巧,您将能够扩展您的电子商务业务,提供更广泛的市场覆盖并提升用户体验。

    ]]>
    Sat, 02 Dec 2023 02:53:40 +0000
    <![CDATA[Magento 2数据库管理和数据迁移:最佳实践和工具]]> https://www.360magento.com/blog/magento-2-database-management-and-data-migration/
  • Magento 2数据库结构
  • 了解Magento 2的数据库结构是有效管理和操作数据库的关键。Magento 2使用EAV(Entity-Attribute-Value)模型来存储和管理数据,这个模型可以灵活地扩展和定制。您应该熟悉Magento 2的核心表和关系,以及自定义模块和扩展可能涉及的表和字段。

    1. 数据库备份和恢复

    定期备份Magento 2的数据库是保护数据完整性的重要步骤。您可以使用数据库管理工具或通过命令行执行备份操作。同时,了解如何恢复数据库备份以应对意外数据丢失或损坏的情况也是至关重要的。

    1. 数据迁移策略

    当您需要将Magento 2网站从一个环境迁移到另一个环境时,制定一个有效的数据迁移策略非常重要。您可以选择使用Magento 2提供的数据迁移工具,如Magento 2迁移工具(Migration Tool)或使用第三方工具和脚本来执行迁移操作。确保在迁移过程中保持数据的一致性和准确性。

    1. 数据迁移工具和技术

    有几个流行的工具和技术可用于Magento 2数据迁移。其中包括Magento 2迁移工具(Migration Tool)、Data Migration Pro(DMC)扩展、第三方ETL(Extract, Transform, Load)工具等。了解这些工具的使用方法和适用场景,可以帮助您更好地管理和执行数据迁移任务。

    总结:

    本篇博文提供了有关Magento 2数据库管理和数据迁移的最佳实践和工具。通过了解Magento 2的数据库结构、备份和恢复数据库、数据迁移策略以及常用的数据迁移工具和技术,您将能够有效地管理和迁移Magento 2网站的数据库。

    ]]>
    Fri, 01 Dec 2023 07:49:03 +0000
    <![CDATA[Magento 2 开发技术指南:构建强大的电子商务网站]]> https://www.360magento.com/blog/magento-2-developer-guide/ Magento 2是一个流行且功能强大的开源电子商务平台,为企业提供了构建可扩展、高性能的在线商店的解决方案。如果您正在考虑使用Magento 2来开发您的电子商务网站,那么本篇博文将为您提供一些有用的技术指导。

    1. Magento 2基本架构

    了解Magento 2的基本架构对于开发者来说至关重要。Magento 2采用了模块化的体系结构,每个功能模块都以自己的方式工作,并可以通过Magento Marketplace进行扩展。熟悉Magento 2的基本组件和模块之间的关系,将帮助您更好地理解和开发您的网站。

    1. 模块开发

    Magento 2的模块开发是扩展和定制平台功能的关键。您可以根据特定需求创建自定义模块,并将其集成到Magento 2中。了解如何创建和配置模块、添加新功能、覆盖现有功能以及处理事件和触发器等关键概念,将帮助您更好地开发和管理自定义模块。

    1. 主题定制

    Magento 2的主题定制使您能够为您的电子商务网站创建独特的外观和用户体验。了解主题的结构、创建自定义主题、修改样式和布局,以及处理静态资源等方面的知识,将使您能够根据品牌需求定制您的网站外观。

    1. 最佳实践

    在开发Magento 2网站时,遵循一些最佳实践可以提高性能、安全性和用户体验。这包括使用缓存和索引、优化数据库查询、进行代码审查和测试、实施安全措施等。本文还将介绍一些最佳实践,以帮助您开发高质量的Magento 2网站。

    总结:

    本篇博文提供了关于Magento 2开发的一些基本指导和资源,帮助您构建功能强大的电子商务网站。通过了解Magento 2的基本架构、模块开发、主题定制以及一些最佳实践,您将能够充分利用Magento 2平台的优势,并为您的客户提供卓越的在线购物体验。

    ]]>
    Fri, 01 Dec 2023 03:47:57 +0000
    <![CDATA[Magento 2性能优化:提升您的电子商务网站速度]]> https://www.360magento.com/blog/magento-e-commerce-website-speed/ 在竞争激烈的电子商务市场中,网站速度是吸引和保留客户的关键因素之一。Magento 2作为一款功能强大的电子商务平台,可以通过一些性能优化技巧来提高网站速度和响应时间。本文将介绍一些Magento 2性能优化的实践方法,帮助您提升电子商务网站的性能。

    1. 使用最新版本的Magento 2:
      始终使用最新版本的Magento 2是提升性能的重要步骤之一。每个版本都包含了对性能的改进和优化,包括代码优化、缓存机制改进和Bug修复等。确保您的网站已经升级到最新版本,以获得最佳性能和安全性。

    2. 启用缓存:
      Magento 2提供了强大的缓存功能,通过缓存页面内容和数据库查询结果,可以大大减少页面加载时间。在Magento 2的后台设置中,您可以启用各种缓存类型,包括页面缓存、块缓存和数据库查询结果缓存等。启用适当的缓存类型可以显著提高网站的响应速度。

    3. 优化图片:
      图片通常是网站加载时间较长的主要原因之一。通过优化图片大小和压缩,可以减少它们的文件大小,从而加快页面加载速度。使用适当的图片格式(如JPEG、PNG)和工具来优化图片,以确保它们在保持质量的同时具有较小的文件大小。

    4. 使用CDN(内容分发网络):
      CDN是一个分布式网络,可以将您的网站内容缓存到全球各个位置的服务器上。当用户访问您的网站时,他们将从最接近他们位置的服务器上加载内容,从而减少了网络延迟和传输时间。使用CDN可以显著提高网站的加载速度和性能。

    5. 优化数据库:
      Magento 2使用数据库存储大量的网站数据,因此优化数据库性能对于提高网站速度至关重要。您可以执行数据库索引优化、删除不必要的数据和日志、优化数据库查询等操作来改善数据库性能。此外,使用数据库缓存和查询缓存也是提高性能的有效方法。

    6. 压缩和合并CSS和JavaScript文件:
      通过压缩和合并网站的CSS和JavaScript文件,可以减少文件的数量和总体文件大小,从而加快页面加载速度。使用合适的工具和技术,将多个CSS文件合并为一个文件,并压缩JavaScript文件,以减少网络请求和提高性能。

    结论:
    通过采取以上的Magento 2性能优化措施,您可以大大提升您的电子商务网站的速度和响应时间。优化网站性能不仅可以提供更好的用户体验,还能提高搜索引擎排名并吸引更多的访问者。始终关注网站性能,并定期评估和优化它,是保持竞争力的关键之一。

    ]]>
    Thu, 30 Nov 2023 07:49:26 +0000
    <![CDATA[Magento 2 数据迁移:顺畅升级您的电子商务平台]]> https://www.360magento.com/blog/magento-data-platform/ 升级到Magento 2是许多电子商务商家追求的目标,因为它提供了更好的功能和性能。然而,数据迁移可能是一个复杂的任务。本文将介绍Magento 2数据迁移的基本原理和技巧,帮助您顺畅升级您的电子商务平台。

    首先,了解数据迁移的范围和目标是很重要的。数据迁移涉及将现有的商店数据从旧的Magento版本或其他电子商务平台迁移到Magento 2。这包括产品、订单、客户、库存、支付信息等。

    在进行数据迁移之前,建议先备份您的现有数据。这将确保在迁移过程中出现问题时可以恢复数据。您可以使用Magento提供的备份工具或第三方备份解决方案进行数据备份。

    接下来,需要评估数据的结构和格式。不同的电子商务平台使用不同的数据结构和格式,因此在迁移数据之前,您需要对源数据进行分析和转换。这可能涉及数据映射、转换和清理等操作。

    在进行数据迁移时,Magento 2提供了Data Migration Tool,它是一个强大的工具,用于处理数据的迁移和转换。该工具使用命令行界面,并提供了丰富的选项和配置文件,以满足各种迁移需求。

    在配置数据迁移工具时,您需要指定源数据和目标数据的连接信息,并定义迁移的范围和规则。根据具体情况,您可能需要编写自定义的映射和转换逻辑,以确保数据正确地迁移到Magento 2。

    在迁移过程中,建议进行逐步迁移,逐个实体地迁移数据。这将有助于排查和解决任何迁移问题,同时减少对商店运营的干扰。

    最后,进行数据迁移后,建议进行数据验证和测试。确保已迁移的数据在Magento 2中正确显示和运行。您可以手动检查数据的准确性,或者使用自动化测试工具进行功能和性能测试。

    综上所述,Magento 2数据迁移是一个复杂但关键的任务。

    ]]>
    Thu, 30 Nov 2023 02:48:11 +0000
    <![CDATA[Magento 2 主题开发:定制您的在线商店外观]]> https://www.360magento.com/blog/magento-theme-customize/ Magento 2是一个功能强大的电子商务平台,允许您根据自己的品牌形象定制在线商店的外观。本文将介绍Magento 2主题开发的基础知识和技巧,帮助您创建一个独特而引人注目的在线商店外观。

    首先,了解Magento 2主题的结构是很重要的。一个Magento 2主题通常由多个文件组成,包括布局文件、模板文件、CSS文件和JavaScript文件。通过编辑这些文件,您可以控制商店的整体布局、页面元素和样式。

    要开始主题开发,您可以从Magento 2的默认主题Luma或Blank开始,或者从头开始创建一个全新的主题。无论您选择哪种方式,都可以通过覆盖和修改现有文件来实现自定义。

    在主题开发过程中,布局文件(layout files)起着重要的作用。布局文件定义了页面的结构和组件的位置。通过修改布局文件,您可以调整页面的布局、添加、删除或重新排列组件。

    此外,模板文件(template files)允许您直接编辑和控制页面的内容。您可以在模板文件中添加动态内容、自定义样式和布局,并与后端代码进行交互。

    在定制主题外观时,CSS和JavaScript文件是不可或缺的。通过编辑这些文件,您可以调整颜色、字体、边距以及添加交互效果和动画等。

    除了基本的主题开发,Magento 2还提供了丰富的主题扩展和市场,您可以从中选择适合您需求的主题。这些主题具有不同的风格和功能,可以满足各种电子商务业务的需求。

    总而言之,Magento 2主题开发为您提供了无限的定制化可能性,帮助您打造一个独特而符合品牌形象的在线商店外观。通过熟悉Magento 2主题的结构和编辑相应的文件,您可以轻松创建一个引人注目的电子商务平台。

    ]]>
    Wed, 29 Nov 2023 06:45:56 +0000
    <![CDATA[Magento 2 扩展开发:定制化您的电子商务功能]]> https://www.360magento.com/blog/magento-ecommerce-custome/ Magento 2是一款功能丰富的电子商务平台,但有时您可能需要特定的功能来满足业务需求。这就是Magento 2扩展开发的重要性所在。本文将介绍Magento 2扩展开发的基础知识和技巧,帮助您定制化您的电子商务功能。

    要开始扩展开发,您需要了解Magento 2的扩展结构。一个Magento 2扩展通常由多个文件和目录组成,包括模块目录、配置文件、控制器、模型、观察者、布局文件等。这些组件共同工作,实现特定的功能。

    首先,您需要创建一个自定义的模块。模块是Magento 2扩展的基本单元,用于组织和管理扩展的代码和资源。创建一个模块需要定义模块的标识符、名称、版本等信息,并将其放置在正确的目录结构中。

    在模块中,您可以创建控制器来处理用户请求和响应。控制器是实现特定功能的核心部分,它接收用户的输入并生成相应的输出。通过编写控制器代码,您可以实现自定义的业务逻辑和流程。

    除了控制器,模型是另一个重要的组件。模型用于处理数据和业务逻辑。通过创建和修改模型,您可以与数据库交互、处理数据操作,并为您的电子商务功能提供数据支持。

    此外,观察者(Observers)也是Magento 2扩展开发中常用的组件。观察者允许您在特定事件发生时执行自定义的操作。通过定义观察者并使用事件和触发器,您可以实现特定功能的扩展和定制。

    在扩展开发过程中,布局文件(layout files)也是不可或缺的。通过编辑布局文件,您可以调整页面的结构和组件的位置,定制页面的布局和外观。

    最后,测试是扩展开发的重要环节。确保您的扩展在不同情况下能够正常运行,并与其他模块和功能兼容。Magento 2提供了丰富的测试工具和框架,帮助您进行单元测试、功能测试和集成测试。

    总结起来,Magento 2扩展开发为您定制化电子商务功能提供了灵活性和无限可能性。通过了解Magento 2扩展的结构和组件,以及熟悉相应的开发技术和工具,您可以创建定制化的功能,满足您的业务需求。

    ]]>
    Wed, 29 Nov 2023 03:47:20 +0000
    <![CDATA[Magento 2:构建强大的电子商务平台]]> https://www.360magento.com/blog/magento-shop-b2c-mage/ Magento 2是一款广泛使用的开源电子商务平台,为企业和商家提供了一个强大而灵活的在线销售解决方案。本文将介绍Magento 2的一些重要特性和优势,以及为什么它是构建强大的电子商务平台的理想选择。

    Magento 2通过提供丰富的功能和灵活的架构,使得构建和管理电子商务网站变得更加容易。它具有以下几个关键特性:

    1. 模块化架构:Magento 2采用模块化的架构,使得扩展和定制变得简单。开发人员可以轻松添加新的功能和扩展,或者自定义现有功能以满足特定的业务需求。

    2. 强大的前端体系:Magento 2采用现代化的前端技术,如HTML5、CSS3和JavaScript框架,为用户提供优雅而响应式的用户体验。它还支持移动设备优先的设计,确保您的网站在各种设备上都能良好运行。

    3. 多店铺支持:Magento 2允许您在单个安装中创建和管理多个在线商店。这对于企业和多品牌零售商来说非常有用,因为它们可以在一个统一的界面下管理所有的在线业务。

    4. 强大的产品目录管理:Magento 2提供了全面的产品目录管理功能。您可以创建和管理产品、分类、价格、库存等,并支持多种产品类型,如简单产品、配置产品和分组产品。

    5. 高级营销工具:Magento 2提供了一套强大的营销工具,如促销规则、优惠券、购物车价格规则等。这些工具可以帮助您制定和执行各种营销策略,吸引和留住客户。

    6. 稳定和可扩展:Magento 2经过了全面的重构和优化,提高了性能和稳定性。它采用现代的技术栈,并具有可扩展的架构,可以处理大量的流量和订单。

    总之,Magento 2是一个功能强大、灵活且可扩展的电子商务平台,适用于各种规模和类型的在线商店。它提供了丰富的功能和工具,帮助企业和商家建立成功的在线业务。如果您正在寻找一个可靠和强大的电子商务平台,Magento 2将是一个理想的选择。

    无论是小型创业公司还是大型企业,Magento 2都为您提供了一套完整的解决方案,满足您的电子商务需求。开始使用Magento 2,构建一个强大而成功的在线商店吧!

    ]]>
    Tue, 28 Nov 2023 07:39:33 +0000
    <![CDATA[Magento 2:为您的电子商务业务带来无限可能]]> https://www.360magento.com/blog/magento-possibilities/ Magento 2是当前最受欢迎和广泛使用的开源电子商务平台之一。作为Magento的最新版本,Magento 2为企业和商家提供了一个功能强大和灵活的在线销售解决方案。本文将探讨Magento 2的关键特性和优势,以及为什么选择Magento 2是为您的电子商务业务带来无限可能的正确决策。

    首先,Magento 2采用了现代化的技术栈和模块化的架构,使得构建和管理电子商务网站变得更加容易。它提供了广泛的功能和灵活的自定义选项,使您能够根据业务需求轻松扩展和定制您的在线商店。无论是创建新的功能模块,还是修改现有功能,Magento 2都提供了强大的工具和API,使开发变得高效而灵活。

    其次,Magento 2具有出色的性能和可扩展性。它经过全面的优化和重构,提高了网站的加载速度和响应能力。不仅如此,Magento 2还支持高并发访问和大规模交易处理,使您能够应对不断增长的业务需求。这对于那些追求扩展和持续增长的企业来说尤为重要。

    Magento 2还提供了出色的用户体验和设计。它具有现代化的前端技术,使您的网站在各种设备上都能完美展现,无论是桌面还是移动设备。此外,Magento 2提供了丰富的主题和布局选项,使您能够轻松创建个性化的品牌形象,吸引并保留用户。

    另一个令人印象深刻的功能是Magento 2的营销工具套件。它提供了广泛的促销规则、优惠券和购物车价格规则等功能,帮助您制定和执行各种营销策略,提高销售和客户参与度。无论是打折促销、交叉销售还是推荐产品,Magento 2都能满足您的需求。

    最后,Magento 2拥有一个庞大的社区和丰富的资源库。您可以从社区获取支持、交流经验,并获取各种扩展和主题来增强您的在线商店。这个活跃的社区为Magento 2提供了持续的更新和改进,确保您始终处于技术的最前沿。

    综上所述,Magento 2是为您的电子商务业务带来无限可能的绝佳选择。它提供了强大的功能、灵活的自定义选项、卓越的性能和用户体验,以及丰富的营销工具和社区支持。无论您是创业初创公司还是大型企业,Magento 2都能满足您的需求并帮助您实现在线销售的成功。赶紧选择Magento 2,为您的电子商务业务开启新的篇章吧!

    ]]>
    Tue, 28 Nov 2023 03:41:51 +0000
    <![CDATA[如何使用Magento 2的工厂创建新的集合实例?]]> https://www.360magento.com/blog/magento-factory-devlop/ 在Magento 2中,您可以使用工厂(Factory)来创建新的集合实例。下面是使用工厂创建新的集合实例的步骤:

    1. 首先,在您的类中注入集合工厂。您可以在构造函数中注入集合工厂,如下所示:
    use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
    
    class YourClass
    {
        protected $productCollectionFactory;
    
        public function __construct(
            ProductCollectionFactory $productCollectionFactory
        ) {
            $this->productCollectionFactory = $productCollectionFactory;
        }
    }
    
    
    1. 然后,您可以使用工厂创建新的集合实例。在需要创建集合的方法中,使用以下代码:
    $productCollection = $this->productCollectionFactory->create();
    1. 现在,您可以使用 $productCollection 对象来操作集合,例如添加过滤器、排序等。以下是一个示例:
    $productCollection->addAttributeToFilter('status', ['eq' => 1])
        ->addAttributeToFilter('price', ['gt' => 100])
        ->setPageSize(10)
        ->setCurPage(1);
    1. 最后,您可以使用 $productCollection 对象来迭代集合中的每个元素,或者获取集合的其他属性。以下是一个示例:
    foreach ($productCollection as $product) {
        echo $product->getName();
    }
    通过使用工厂创建新的集合实例,您可以在Magento 2中更好地管理和操作数据。希望这个解答对您有帮助!
    ]]>
    Mon, 27 Nov 2023 07:50:53 +0000
    <![CDATA[magento2除了集合工厂,还有其他方法可以创建新的集合实例吗?]]> https://www.360magento.com/blog/magento-collection-factory/
  • 使用集合管理器(Collection Manager):集合管理器是Magento 2中的一个核心类,它可以帮助您创建和管理集合实例。您可以通过依赖注入将集合管理器注入到您的类中,并使用它来创建新的集合实例。以下是一个示例:
  • use Magento\Framework\App\ResourceConnection;
    use Magento\Framework\EntityManager\MetadataPool;
    use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
    use Magento\Framework\Model\ResourceModel\Db\Collection\CollectionFactoryInterface;
    
    class YourClass
    {
        protected $collectionFactory;
    
        public function __construct(
            CollectionFactoryInterface $collectionFactory
        ) {
            $this->collectionFactory = $collectionFactory;
        }
    
        public function createNewCollection()
        {
            $collection = $this->collectionFactory->create();
            // 对集合进行操作
            return $collection;
        }
    }
    1. 使用对象管理器(Object Manager):虽然不推荐直接使用对象管理器,但在某些情况下,您可以使用对象管理器来创建新的集合实例。以下是一个示例:
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $collection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\Collection');
    // 对集合进行操作
    请注意,使用对象管理器可能会导致依赖注入的问题,并且不符合Magento 2的最佳实践。因此,建议优先考虑使用集合工厂或集合管理器来创建新的集合实例。
    ]]>
    Mon, 27 Nov 2023 03:54:37 +0000
    <![CDATA[Magento的高级搜索和过滤功能如何帮助顾客找到他们需要的产品?]]> https://www.360magento.com/blog/magento-advance-search/ Magento的高级搜索和过滤功能通过以下方式帮助顾客找到他们需要的产品:

    1. 关键词搜索:顾客可以在Magento的搜索栏中输入关键词,例如产品名称、描述、型号等,以快速找到相关的产品。这使顾客能够通过简单的关键词搜索快速定位到他们感兴趣的产品。

    2. 价格范围筛选:Magento允许顾客根据价格范围进行筛选,以便在他们预算范围内查找产品。顾客可以设置最低和最高价格,系统将只显示符合这个价格范围的产品,帮助顾客更快地找到合适的产品。

    3. 属性筛选:Magento允许企业为产品定义各种属性,例如颜色、尺寸、材质等。顾客可以使用这些属性进行筛选,以便根据自己的偏好和需求找到符合要求的产品。例如,顾客可以选择特定颜色的衣服或特定尺寸的电子设备。

    4. 类别筛选:Magento的产品目录可以根据不同的类别进行组织和分类。顾客可以通过选择特定的类别来缩小搜索范围,只显示该类别下的产品。这使顾客能够更快地找到他们感兴趣的产品,而无需浏览整个产品目录。

    5. 标签和标识筛选:Magento允许企业为产品添加标签和标识,例如热销、新品、特价等。顾客可以使用这些标签和标识进行筛选,以便找到符合自己需求的特定类型的产品。这使顾客能够更轻松地发现促销产品或最新上市的产品。

    通过这些高级搜索和过滤功能,顾客可以根据自己的需求和偏好快速准确地找到他们需要的产品。这提供了更好的购物体验,节省了顾客的时间和精力,并增加了他们对企业的满意度。

    ]]>
    Sun, 26 Nov 2023 07:50:04 +0000
    <![CDATA[如何在Magento的搜索栏中实现自动补全功能?]]> https://www.360magento.com/blog/magento-link-search-by-customer/ 要在Magento的搜索栏中实现自动补全功能,可以按照以下步骤进行操作:

    1. 登录到Magento的后台管理面板。
    2. 导航到“Stores(商店)”>“Configuration(配置)”>“Catalog(目录)”>“Catalog Search(目录搜索)”。
    3. 在“Search Options(搜索选项)”部分,找到“Enable Search Suggestions(启用搜索建议)”选项。
    4. 将“Enable Search Suggestions(启用搜索建议)”设置为“Yes(是)”。
    5. 保存配置更改。

    完成上述步骤后,Magento的搜索栏将开始显示自动补全建议。当顾客在搜索栏中输入关键词时,系统将根据已有的产品和搜索历史提供相关的建议。这些建议将在下拉菜单中显示,帮助顾客更快地找到他们想要的产品。

    请注意,要使自动补全功能正常工作,您的Magento网站需要有足够的产品数据和搜索历史数据。此外,确保您的服务器和数据库能够处理自动补全功能的负载。

    通过在Magento的搜索栏中启用自动补全功能,您可以提供更智能和便捷的搜索体验,帮助顾客更快速地找到他们需要的产品。

    ]]>
    Sun, 26 Nov 2023 03:52:33 +0000
    <![CDATA[Magento 的电子商务功能是如何帮助公司提供无缝购物体验的?]]> https://www.360magento.com/blog/mageno-company-shop/ Sat, 25 Nov 2023 07:45:48 +0000 <![CDATA[Magento的栅格系统如何帮助开发人员创建响应式布局?]]> https://www.360magento.com/blog/magento-grid-dev/ Magento的栅格系统是一种基于栅格布局的响应式设计工具,可以帮助开发人员创建适应不同设备的响应式布局。以下是栅格系统如何帮助开发人员创建响应式布局的几个关键点:

    1. 划分页面:栅格系统将页面划分为多个列,开发人员可以根据需要将内容放置在不同的列中。这样可以确保页面的布局在不同设备上自动适应。

    2. 响应式列:栅格系统中的列具有响应式特性,它们可以根据设备的屏幕大小自动调整宽度。开发人员可以定义每个列在不同屏幕尺寸下所占的宽度比例,从而实现自适应布局。

    3. 响应式偏移:栅格系统还支持响应式偏移,开发人员可以通过设置列的偏移量来调整内容在页面上的位置。这对于在不同设备上重新排列内容非常有用。

    4. 响应式嵌套:栅格系统允许开发人员在列内部创建更深层次的嵌套结构。这样可以更灵活地组织和布局页面的内容,以适应不同设备的显示需求。

    通过使用Magento的栅格系统,开发人员可以轻松创建具有响应式布局的网页。栅格系统提供了一种灵活的方式来划分和组织页面的内容,使其能够在不同设备上自动适应并提供一致的用户体验。开发人员可以根据需要定义列的宽度比例和偏移量,以实现所需的布局效果

    ]]>
    Sat, 25 Nov 2023 03:43:47 +0000
    <![CDATA[Magento的响应式设计如何提供一致的购物体验?]]> https://www.360magento.com/blog/magento-respose/ Magento的响应式设计通过自动适应不同设备的屏幕大小和分辨率,提供一致的购物体验。以下是Magento响应式设计如何实现一致购物体验的几个关键点:

    1. 自适应布局:Magento的响应式设计使用自适应布局,使网站的布局和元素能够根据设备的屏幕大小和分辨率进行调整。无论用户是在桌面电脑、平板电脑还是手机上访问网站,页面的布局都会自动适应,确保内容的可读性和可操作性。

    2. 图片优化:Magento的响应式设计会对图片进行优化,使其在不同设备上加载速度更快。通过使用适当的图像压缩和缩放技术,确保图片在不同屏幕上显示清晰,并且加载时间不会过长。

    3. 导航和菜单:Magento的响应式设计会对导航和菜单进行优化,以适应不同设备的触摸操作和屏幕尺寸。在移动设备上,导航和菜单通常会以折叠或下拉的形式呈现,以节省屏幕空间并提供更好的用户体验。

    4. 内容排版:Magento的响应式设计会对内容进行排版调整,以适应不同设备的屏幕大小和分辨率。文字、标题和其他内容元素会根据屏幕尺寸进行调整,以确保用户可以轻松阅读和理解页面上的信息。

    5. 表单和输入:Magento的响应式设计会对表单和输入字段进行优化,以适应不同设备的触摸操作和输入方式。输入字段的大小和间距会根据屏幕尺寸进行调整,以提供更好的用户体验和易用性。

    通过这些响应式设计的优化,Magento确保用户在不同设备上都能够获得一致的购物体验。无论用户是在桌面电脑、平板电脑还是手机上访问网站,他们都可以轻松浏览产品、添加到购物车并完成购买,从而提高用户满意度和转化率。

    ]]>
    Fri, 24 Nov 2023 07:41:45 +0000
    <![CDATA[Magento的响应式设计如何实现自适应布局]]> https://www.360magento.com/blog/magento-res-layout/ Magento的响应式设计通过以下方式实现自适应布局:

    1. 媒体查询(Media Queries):Magento使用CSS3的媒体查询功能来根据设备的屏幕大小和分辨率应用不同的样式。媒体查询允许开发人员根据不同的屏幕尺寸定义不同的CSS规则,从而实现自适应布局。

    2. 栅格系统(Grid System):Magento使用栅格系统来创建响应式布局。栅格系统将页面划分为多个列,开发人员可以根据不同的屏幕尺寸和布局需求,将内容放置在不同的列中。这样可以确保页面在不同设备上的布局和排列方式都能够自动适应。

    3. 弹性图像(Flexible Images):Magento使用弹性图像技术来确保图像在不同设备上的自适应显示。弹性图像使用CSS属性来控制图像的大小和比例,使其能够根据屏幕尺寸自动调整大小,从而适应不同设备的显示需求。

    4. 响应式导航(Responsive Navigation):Magento的响应式设计还包括响应式导航菜单。在小屏幕设备上,导航菜单通常会以折叠或下拉的形式呈现,以节省屏幕空间并提供更好的用户体验。当屏幕尺寸增大时,导航菜单会自动展开或以水平方式显示,以适应更大的屏幕空间。

    通过这些技术和方法,Magento的响应式设计能够实现自适应布局,使网站能够在不同设备上提供一致的用户体验。用户无论是在桌面电脑、平板电脑还是手机上访问网站,都能够获得良好的浏览和交互体验。

    ]]>
    Fri, 24 Nov 2023 03:42:35 +0000
    <![CDATA[关于magento的介绍]]> https://www.360magento.com/blog/magento-detial/ Magento是一个基于开源技术构建的电子商务平台,由Magento, Inc.开发。它于2008年首次发布,使用PHP编写。目前,Adobe已将Magento Commerce整合到Adobe Commerce中,但Magento Open Source品牌和支持保持不变。Magento是最受欢迎的电子商务平台之一,被许多顶级电子商务网站采用。以下是关于Magento的一些事实、优势和劣势。

    Magento的优势包括:

    1. 提供卓越的可扩展性和性能。
    2. 提供增强的用户购物体验。
    3. 提供强大的平台功能。
    4. 兼容移动设备。
    5. 可扩展性强,支持高级SEO功能。
    6. 提供可定制的安全功能。
    7. 支持市场集成和第三方集成。
    8. 提供智能搜索选项。
    9. 可选择任何托管服务。
    10. 拥有庞大的专业社区。

    Magento的一些主要功能包括:

    1. 产品管理:管理产品目录、库存和价格。
    2. 类别管理:创建和管理产品类别。
    3. 国际支持:支持多语言和多货币。
    4. 客户账户:管理客户账户和订单。
    5. 库存管理:跟踪库存和库存变化。
    6. 促销和营销工具:提供各种促销和营销工具。
    7. 搜索技术:提供高级搜索功能。
    8. 客户服务:提供客户支持和服务。
    9. 分析和报告:提供分析和报告功能。

    Magento还提供了许多扩展,这些扩展可以增加特定的功能。扩展是一组代码,用于实现Magento的特定功能。

    Magento有两个版本:Magento 1和Magento 2。Magento 1是较旧的版本,稳定性较高,但即将到达生命周期的尽头。Magento 2是较新的版本,功能更强大,但复杂性也更高。

    Magento有两个版本:Magento Open Source(以前称为Magento Community Edition)和Magento Commerce(以前称为Magento Enterprise Edition)。Magento Open Source是免费的,提供基本功能。Magento Commerce是付费版本,提供更多高级功能和支持。

    总之,Magento是一个功能强大、灵活可定制的电子商务平台,适用于个人和企业建立长期、专业的电子商务网站。它具有丰富的功能和强大的社区支持,可以满足各种电子商务需求。

    ]]>
    Thu, 23 Nov 2023 07:39:31 +0000
    <![CDATA[Magento的可扩展性和性能如何提高用户购物体验?]]> https://www.360magento.com/blog/magento-2mdsdms-shop/ Magento通过其可扩展性和性能提高用户购物体验的方式有以下几点:

    1. 快速加载速度:Magento通过使用高级缓存技术和优化代码来提高网站的加载速度。快速加载速度可以减少用户等待时间,提高用户体验,并降低购物车放弃率。

    2. 响应式设计:Magento具有响应式设计,可以自动适应不同设备的屏幕大小和分辨率。这意味着用户无论使用桌面电脑、平板电脑还是手机,都可以获得一致的购物体验。

    3. 多语言和多货币支持:Magento支持多语言和多货币功能,使您能够为全球用户提供本地化的购物体验。用户可以在他们熟悉的语言和货币下浏览和购买产品,这提高了用户的舒适度和满意度。

    4. 强大的搜索功能:Magento具有强大的搜索功能,可以帮助用户快速找到他们想要的产品。它支持高级搜索选项,如过滤器、排序和自定义搜索条件,使用户能够更轻松地浏览和筛选产品。

    5. 个性化推荐:Magento可以根据用户的浏览和购买历史,提供个性化的产品推荐。这可以帮助用户发现他们可能感兴趣的产品,提高购买意愿和转化率。

    6. 简化的结账流程:Magento提供了简化的结账流程,使用户能够快速、轻松地完成购买。它支持多种支付方式和快速结账选项,如快速填写表单和保存付款信息,提高了用户的购物体验。

    总之,Magento通过其可扩展性和性能优化,提供了一个快速、响应式和个性化的购物体验。这些功能可以提高用户的满意度和购买意愿,帮助您的电子商务网站取得成功。

    ]]>
    Thu, 23 Nov 2023 03:33:12 +0000
    <![CDATA[创建可配置产品:Magento 2的灵活性与个性化定制的利器]]> https://www.360magento.com/blog/Magento-2-create-configurable/ 对于电商平台而言,提供灵活的产品配置和个性化定制是吸引客户和提高销售的重要因素之一。Magento 2提供了强大的功能,使您能够轻松创建可配置产品,满足客户的不同需求。本文将详细介绍在Magento 2中创建可配置产品的过程和优势。

    1. 什么是可配置产品?

    可配置产品是指具有多个配置选项和变体的产品。例如,一件衣服的可配置选项可能包括颜色、尺寸和款式等。通过选择不同的配置选项,客户可以根据自己的喜好和需求来个性化定制产品。

    2. 创建可配置产品的步骤:

    在Magento 2中创建可配置产品需要按照以下步骤进行操作:

    步骤 1:创建属性:在Magento后台,创建与产品相关的属性。例如,对于衣服,您可以创建颜色和尺寸属性。

    步骤 2:创建属性集(Attribute Set):属性集是一组属性的集合,用于定义产品的属性。创建一个属性集,并将相关属性添加到该属性集中。

    步骤 3:创建可配置产品:在Magento后台,创建一个新产品,并选择刚才创建的属性集。在产品配置选项中,启用"Create Configurations"选项,并选择相关的属性。

    步骤 4:配置选项设置:为每个属性设置相应的选项值。例如,对于颜色属性,您可以设置红色、蓝色和绿色等选项。

    步骤 5:创建产品变体:通过选择不同的配置选项值,创建产品的不同变体。例如,在颜色属性中选择红色,在尺寸属性中选择大号,就可以创建一个红色大号的产品变体。

    3. 可配置产品的优势:

    创建可配置产品带来了多个优势,包括:

    a. 个性化定制:可配置产品允许客户根据自己的需求和偏好进行个性化定制,提供更好的购物体验。

    b. 简化管理:通过使用可配置产品,您可以将多个变体整合到一个产品页面中,简化产品管理和库存管理。

    c. 提高销售:提供更多的选择和个性化定制选项可以吸引更多的客户,并增加销售机会。

    ]]>
    Wed, 22 Nov 2023 08:42:36 +0000
    <![CDATA[提高协作效率——Magento后台多用户登录功能的优势与用法]]> https://www.360magento.com/blog/multiple-admin-users-login/ 在一个电商平台上,有效的团队协作是实现高效运营和管理的关键因素之一。Magento电商平台提供了一项强大的功能——后台多用户登录,它允许多个用户同时登录Magento后台管理界面。本文将详细介绍Magento后台多用户登录功能的优势和用法,以帮助您提高团队的协作效率。

    1. 优势:

    Magento后台多用户登录功能带来了许多优势,包括:

    a. 提高团队协作效率:多用户登录功能使多个团队成员能够同时登录后台管理界面,无需等待其他用户退出登录。这样,不同的团队成员可以同时处理各自的任务,大大提高了团队的协作效率。

    b. 灵活的权限管理:Magento提供了灵活的权限管理系统,您可以根据用户的角色和职责,为每个用户分配特定的权限。这样,您可以确保每个用户只能访问其需要的功能和数据,提高安全性和数据保护。

    c. 跟踪和审计:通过多用户登录功能,您可以轻松跟踪每个用户的活动和操作。这对于审计和故障排除非常有用,您可以快速了解到底是哪个用户进行了特定的更改或操作。

    2. 配置和使用Magento后台多用户登录功能:

    要配置和使用Magento后台多用户登录功能,您可以按照以下步骤进行操作:

    步骤 1:创建用户角色:在Magento后台,创建不同的用户角色,并为每个角色分配相应的权限。

    步骤 2:创建用户账号:为每个团队成员创建独立的用户账号,并将其分配给相应的用户角色。

    步骤 3:启用多用户登录:在Magento后台的系统设置中,启用多用户登录功能。

    步骤 4:登录后台:团队成员可以使用自己的用户账号登录Magento后台,开始进行相应的操作和管理任务。

    ]]>
    Wed, 22 Nov 2023 03:00:00 +0000
    <![CDATA[Magento 2教程:如何创建新的商店视图]]> https://www.360magento.com/blog/magento2-create-new-store-view/ 在Magento 2中,商店视图(Store View)是一种用于展示商城内容的配置。通过创建新的商店视图,您可以将商城扩展到不同的语言、货币和地理位置,以满足全球用户的需求,并提供个性化的商城体验。下面是在Magento 2中创建新的商店视图的简明教程。

    步骤1:登录到Magento 2后台管理面板。

    • 使用管理员帐户登录到Magento 2后台。

    步骤2:导航到商店视图设置。

    • 在Magento 2的管理面板中,导航到"商店" > "设置(Configuration)"。
    • 在左侧导航中,找到"商店"部分,并点击"商店视图(Store View)"选项。

    步骤3:创建新的商店视图。

    • 在商店视图页面,点击"创建商店视图(Create Store View)"按钮。
    • 在"商店(Store)"字段中,选择要与新视图关联的商店。
    • 在"名称(Name)"字段中,输入商店视图的名称,例如"英文商店"。
    • 在"代码(Code)"字段中,输入商店视图的唯一代码,例如"en"。
    • 在"状态(Status)"字段中,选择"启用(Enabled)"以激活商店视图。
    • 在"排序(Sort Order)"字段中,输入商店视图的排序顺序(可选)。
    • 点击"保存(Save Store View)"按钮以创建商店视图。

    步骤4:配置商店视图选项(可选)。

    • 在商店视图页面,找到您刚创建的商店视图,并点击进入编辑页面。
    • 在编辑页面,您可以配置商店视图的各种选项,如语言、货币、时区等。
    • 根据您的需求进行相应的配置,并点击"保存(Save Store View)"按钮以保存更改。

    通过按照上述步骤,在Magento 2中创建新的商店视图将变得简单而直观。您可以根据您的业务需求创建多个商店视图,以满足不同目标市场的需求,并提供个性化的商城体验。

    ]]>
    Tue, 21 Nov 2023 07:00:00 +0000
    <![CDATA[Magento 2教程:如何创建CMS页面重写]]> https://www.360magento.com/blog/magento2-create-cms-page-rewrite/ 在Magento 2中,CMS页面重写允许您自定义CMS页面的链接路径和URL。这对于优化页面链接的可读性、提高用户体验和搜索引擎优化(SEO)效果非常有用。通过创建CMS页面重写,您可以使用自定义的URL路径来替代默认的CMS页面链接,使其更加友好和易于理解。下面是在Magento 2中创建CMS页面重写的简明教程。

    步骤1:登录到Magento 2后台管理面板。

    • 使用管理员帐户登录到Magento 2后台。

    步骤2:导航到CMS页面设置。

    • 在Magento 2的管理面板中,导航到"内容" > "页面(Pages)"。
    • 找到您想要创建URL重写的CMS页面,点击进入页面编辑页面。

    步骤3:创建URL重写。

    • 在页面编辑页面的左侧导航中,展开"搜索引擎优化(SEO)"部分。
    • 在"URL键(URL Key)"字段中,输入您想要自定义的页面链接路径。
    • Magento 2会自动检测并验证URL键的唯一性。如果URL键已经被使用,您需要选择其他唯一的键。
    • 点击"保存(Save)"按钮以保存页面更改。

    步骤4:刷新前台页面并查看结果。

    • 在Magento 2后台管理面板的顶部菜单中,点击"清除缓存(Flush Cache Storage)"。
    • 访问您的Magento 2商城,并导航到已创建URL重写的CMS页面。
    • 您将看到页面链接已被自定义为新的URL路径。

    通过按照上述步骤,在Magento 2中创建CMS页面重写将变得简单而直观。请注意,创建URL重写后,确保更新站点地图和搜索引擎索引,以确保新的URL路径被正确引导和索引。

    ]]>
    Tue, 21 Nov 2023 03:43:02 +0000
    <![CDATA[Magento 2教程:如何创建产品URL重写]]> https://www.360magento.com/blog/magento2-create-product-url-rewrite/ 在Magento 2中,产品URL重写是一种强大的功能,可以帮助您优化产品链接的结构和可读性,同时提升搜索引擎优化(SEO)效果。通过创建产品URL重写,您可以使用自定义的URL路径替代默认的产品链接,使其更加友好和易于理解。下面是在Magento 2中创建产品URL重写的简明教程。

    步骤1:登录到Magento 2后台管理面板。

    • 使用管理员帐户登录到Magento 2后台。

    步骤2:导航到产品URL重写设置。

    • 在Magento 2的管理面板中,导航到"产品" > "目录(Catalog)" > "产品"。
    • 找到您想要创建URL重写的产品,点击进入产品编辑页面。

    步骤3:创建URL重写。

    • 在产品编辑页面的左侧导航中,展开"搜索引擎优化(SEO)"部分。
    • 在"URL键(URL Key)"字段中,输入您想要自定义的产品链接路径。
    • Magento 2会自动检测并验证URL键的唯一性。如果URL键已经被使用,您需要选择其他唯一的键。
    • 点击"保存(Save)"按钮以保存产品更改。

    步骤4:刷新前台页面并查看结果。

    • 在Magento 2后台管理面板的顶部菜单中,点击"清除缓存(Flush Cache Storage)"。
    • 访问您的Magento 2商城,并导航到已创建URL重写的产品页面。
    • 您将看到产品链接已被自定义为新的URL路径。

    通过按照上述步骤,在Magento 2中创建产品URL重写将变得简单而直观。请注意,创建URL重写后,确保更新站点地图和搜索引擎索引,以确保新的URL路径被正确引导和索引。

    ]]>
    Mon, 20 Nov 2023 07:42:08 +0000
    <![CDATA[Magento 2教程:如何在主页上插入产品]]> https://www.360magento.com/blog/magento2-insert-products-homepage/ 主页是Magento 2商城中最重要的页面之一,为您的客户提供了第一印象和导航入口。通过在主页上插入产品,您可以突出展示您的热门产品、特别推荐或促销活动,吸引客户并提高销售。下面是在Magento 2主页上插入产品的简明教程。

    步骤1:登录到Magento 2后台管理面板。

    • 使用管理员帐户登录到Magento 2后台。

    步骤2:创建产品的产品块(Product Block)。

    • 在Magento 2的管理面板中,导航到"内容" > "块(Blocks)"。
    • 点击"添加新块(Add New Block)"按钮。
    • 在"标识符(Identifier)"字段中输入一个唯一的标识符,例如"homepage-products"。
    • 在"标题(Title)"字段中输入块的标题,例如"主页产品"。
    • 在"内容(Content)"字段中输入以下代码:
      {{widget type="Magento\Catalog\Block\Product\Widget\NewWidget" display_type="all_products"
      products_count="4" template="product/widget/new/content/new_grid.phtml"}}
      
    • 点击"保存和继续编辑(Save and Continue Edit)"按钮。

    步骤3:编辑主页布局并插入产品块。

    • 在Magento 2的管理面板中,导航到"内容" > "页面(Pages)"。
    • 找到并点击编辑您的主页。
    • 在主页编辑器中,找到您想插入产品的位置,将光标放置在那里。
    • 点击编辑器工具栏上的"插入变量(Insert Variable)"按钮。
    • 在弹出窗口中,选择"产品块(Blocks)"选项。
    • 在下拉菜单中选择您在步骤2中创建的产品块(例如"主页产品")。
    • 点击"插入(Insert)"按钮。
    • 点击"保存(Save)"按钮以保存主页更改。

    步骤4:刷新前台页面并查看结果。

    • 在Magento 2后台管理面板的顶部菜单中,点击"清除缓存(Flush Cache Storage)"。
    • 访问您的Magento 2商城的主页,刷新页面,您将看到插入的产品块显示在主页上。

    通过按照上述步骤,在Magento 2主页上插入产品将变得简单而直观。您可以根据需要自定义产品块的数量、样式和展示方式,以实现最佳的产品展示效果。

    ]]>
    Mon, 20 Nov 2023 03:40:34 +0000
    <![CDATA[Magento 2订单状态工作流程详解]]> https://www.360magento.com/blog/magento2-order-status-workflow/ 订单状态是Magento 2中跟踪和管理订单进程的关键组成部分。了解订单状态的工作流程对于运营一个Magento 2商城至关重要。下面是Magento 2中订单状态的详细工作流程。

    1. 新订单(New):

      • 当客户成功下单后,订单状态被设置为新订单。
      • 在此状态下,商家可以进行一些操作,如编辑订单、添加备注等。
      • 新订单通常需要进一步处理,以满足库存、支付和配送等需求。
    2. 处理中(Processing):

      • 当商家开始处理订单时,订单状态会从新订单转换为处理中。
      • 处理中状态表示商家正在处理订单,并可能涉及库存扣减、支付确认等操作。
    3. 完成(Complete):

      • 当订单中的所有产品都已经准备好并发货时,订单状态会从处理中转换为完成。
      • 完成状态表示订单已经处理完毕,并且产品已经交付给客户。
    4. 部分发货(Partially Shipped):

      • 如果订单中的一部分产品已经发货,但还有其他产品未发货,订单状态会变为部分发货。
      • 部分发货状态允许商家在等待所有产品准备好后一次性发货。
    5. 部分退款(Partially Refunded):

      • 如果订单中的一部分金额被退款,订单状态会变为部分退款。
      • 部分退款状态表示商家已经处理了部分退款请求。
    6. 已取消(Canceled):

      • 如果订单在处理过程中被取消,或者客户请求取消订单,订单状态会变为已取消。
      • 已取消状态表示订单已被取消,不再需要进一步处理。
    7. 已关闭(Closed):

      • 当订单完成并且不再需要进一步操作时,订单状态会变为已关闭。
      • 已关闭状态表示订单已经结束,不再进行任何操作。

    请注意,以上是Magento 2中常见的订单状态,具体的订单状态可能会因商城设置和定制而有所不同。

    通过了解Magento 2中订单状态的工作流程,您可以更好地管理和跟踪订单的状态变化,从而提供更好的客户体验和订单处理效率。

    ]]>
    Sun, 19 Nov 2023 07:37:42 +0000
    <![CDATA[Magento 2备份指南:保护您的商城数据]]> https://www.360magento.com/blog/magento2-backup-guide/ 在Magento 2开发中,定期进行备份是保护您商城数据的重要措施之一。本文将为您提供一份详细的Magento 2备份指南,涵盖了数据库备份、文件备份以及备份策略的建议,帮助您确保数据的安全性和可恢复性。

    正文:
    在运营一个Magento 2商城时,保护商城数据的安全性至关重要。定期备份是一项关键任务,以确保您的数据在意外事件发生时能够恢复。以下是一份Magento 2备份指南,帮助您制定备份策略并执行备份操作。

    1. 数据库备份:

      • 使用命令行工具(如mysqldump)或数据库管理工具(如phpMyAdmin)创建数据库备份。
      • 将备份文件保存在安全的位置,最好是离线存储或云存储服务。
    2. 文件备份:

      • 备份Magento 2的代码文件和媒体文件(如产品图片、CMS页面图片等)。
      • 使用文件同步工具(如rsync)或压缩工具(如tar)创建文件备份。
      • 将备份文件保存在安全的位置,与数据库备份分开存储。
    3. 定期备份策略:

      • 确定备份频率,根据您的商城活动和数据增长情况制定备份计划。通常建议每日备份。
      • 考虑创建完整备份和增量备份的组合,以减少备份时间和存储空间的使用。
      • 保留历史备份,以便您可以根据需要恢复到特定时间点的数据。
    4. 自动化备份:

      • 配置定时任务或使用备份工具自动执行备份操作,确保备份过程的一致性和可靠性。
      • 监控备份过程,确保备份成功完成,并及时处理任何备份错误或警告。
    5. 测试和恢复:

      • 定期测试备份文件的完整性和可恢复性,确保备份数据的有效性。
      • 在安全的测试环境中进行恢复测试,以验证备份的可用性和恢复过程的正确性。

    通过遵循这些Magento 2备份指南,您可以确保商城数据的安全性和可恢复性。备份是一项关键任务,不容忽视。

    ]]>
    Sun, 19 Nov 2023 03:29:56 +0000
    <![CDATA[10个实用的Magento 2开发小技巧]]> https://www.360magento.com/blog/magento2-development-tips/ 在Magento 2开发中,掌握一些实用的小技巧可以提高您的效率并优化您的代码。本文将分享10个实用的Magento 2开发小技巧,涵盖了从调试到性能优化的各个方面,帮助您更好地开发和定制Magento 2。

    正文:
    Magento 2是一个功能强大的电子商务平台,为开发人员提供了丰富的工具和功能。以下是一些实用的Magento 2开发小技巧,可以帮助您更好地利用这个平台:

    1. 使用模板路径提示:在开发过程中,您可以在Magento 2后台启用模板路径提示,以快速找到当前页面使用的模板文件的路径。

    2. 自定义日志记录:使用Magento 2的日志记录功能,您可以在代码中轻松添加自定义日志语句,以便调试和跟踪问题。

    3. 使用插件(Plugins)进行修改:Magento 2的插件机制允许您在不修改核心代码的情况下修改或扩展现有的类和方法。

    4. 使用代码生成器:Magento 2提供了代码生成器(Code Generator)工具,可以帮助您快速生成模块、控制器、模型等基本代码结构。

    5. 启用缓存:在开发过程中,及时禁用或清除缓存以查看实时更改。但在生产环境中,启用缓存以提高性能是非常重要的。

    6. 使用命令行工具:Magento 2提供了许多强大的命令行工具,如数据库迁移、静态资源部署、索引重建等,可以简化开发流程。

    7. 使用代码嗅探器(Code Sniffer):Magento 2附带了一个代码嗅探器工具,可以帮助您遵循Magento开发最佳实践,并确保代码质量。

    8. 优化数据库查询:在编写自定义代码时,尽量减少数据库查询次数,并使用Magento 2提供的查询优化技术,如使用索引、批处理操作等。

    9. 启用Varnish缓存:Varnish是一个流行的HTTP加速器,通过缓存页面内容来提高Magento 2的性能。在生产环境中启用Varnish缓存可以显著提升网站的加载速度。

    10. 及时更新和备份:确保您的Magento 2安装是最新版本,并定期备份您的代码和数据库,以便在需要时进行恢复。

    这些实用的Magento 2开发小技巧可以帮助您更高效地开发和定制Magento 2,并提升您的开发体验。

    ]]>
    Sat, 18 Nov 2023 08:28:02 +0000
    <![CDATA[使用观察者模式扩展Magento 2功能]]> https://www.360magento.com/blog/magento2-observer-pattern/ 观察者模式是Magento 2开发中一个强大而灵活的工具,它允许您在系统中的特定事件发生时执行自定义操作。本文将介绍Magento 2中的观察者模式,并提供一些示例代码,帮助您理解如何使用观察者模式来扩展和定制Magento 2的功能。

    正文:
    在Magento 2中,观察者模式是通过事件(Event)和调度程序(Dispatcher)的结合来实现的。事件是系统中发生的特定动作或状态的表示,而调度程序则负责监听和触发这些事件。当事件发生时,调度程序将通知所有注册的观察者,并执行它们所定义的操作。

    首先,我们需要定义一个触发事件的点,并在需要监听的地方注册观察者。例如,假设我们想在添加商品到购物车时执行一些自定义操作。我们可以在checkout_cart_add_product_complete事件上注册一个观察者。

    以下是一个基本的观察者类的示例代码:

    php
    <?php
    namespace Vendor\Module\Observer;
    
    use Magento\Framework\Event\ObserverInterface;
    
    class AddToCartObserver implements ObserverInterface
    {
        public function execute(\Magento\Framework\Event\Observer $observer)
        {
            // 在此处编写您的自定义操作代码
        }
    }
    

    然后,我们需要在模块的etc/events.xml文件中定义观察者的配置:

    xml
    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
        <event name="checkout_cart_add_product_complete">
            <observer name="vendor_module_addtocart_observer" instance="Vendor\Module\Observer\AddToCartObserver" />
        </event>
    </config>
    

    在上述示例中,我们将checkout_cart_add_product_complete事件与Vendor\Module\Observer\AddToCartObserver观察者关联起来。当该事件在系统中被触发时,观察者的execute方法将会被调用。

    您可以根据需要注册多个观察者,并在每个观察者的execute方法中编写自己的逻辑。

    通过使用观察者模式,您可以方便地扩展和定制Magento 2的功能,而无需修改核心代码。观察者模式使得系统的各个部分能够松散地耦合在一起,提供了更高的可维护性和可扩展性。

    ]]>
    Sat, 18 Nov 2023 03:27:02 +0000
    <![CDATA[在Magento中使用XML在首页插入静态块的方法]]> https://www.360magento.com/blog/magento-insert-static-block-homepage-xml/ 在Magento中,您可以使用XML布局文件来在首页或其他页面中插入静态块,以便在页面上显示自定义内容。本篇博文将介绍如何使用XML在Magento的首页插入静态块。

    步骤 1:登录到Magento后台管理区域
    使用管理员凭据登录到您的Magento后台管理区域。

    步骤 2:创建静态块
    在Magento后台管理区域,导航到左侧菜单中的“内容” > “块”。点击“创建新块”按钮,创建一个新的静态块。填写块的相关信息,包括标识符和内容。

    步骤 3:编辑首页布局文件
    在Magento的主题中,找到用于首页的布局文件。通常,首页的布局文件位于以下路径:`app/design/frontend/{Vendor}/{Theme}/Magento_Theme/layout/default.xml`。如果您使用的是自定义主题,请相应地修改路径。

    步骤 4:插入静态块的XML代码
    在首页布局文件中,找到`<body>`标签,并在其中插入以下XML代码:

    ```xml
    <referenceContainer name="content">
    <block class="Magento\Cms\Block\Block" name="your_block_name">
    <arguments>
    <argument name="block_id" xsi:type="string">your_block_identifier</argument>
    </arguments>
    </block>
    </referenceContainer>
    ```

    将`your_block_name`替换为您希望为该静态块定义的名称,并将`your_block_identifier`替换为之前创建的静态块的标识符。

    步骤 5:保存并清除缓存
    保存并关闭首页布局文件。然后,登录到Magento后台管理区域,导航到“系统” > “缓存管理”,并清除页面缓存,以便使更改生效。

    步骤 6:查看首页上的静态块
    现在,打开Magento商店的首页,您将看到之前创建的静态块已成功插入到首页中,并显示相应的内容。

    使用XML在Magento的首页插入静态块使您能够轻松地自定义首页内容,并在页面上显示自定义的静态块。

    ]]>
    Fri, 17 Nov 2023 07:16:24 +0000
    <![CDATA[在Magento 2中自定义首页页面的方法]]> https://www.360magento.com/blog/magento2-customize-homepage/

    Magento 2是一个功能强大的电子商务平台,允许您自定义和配置各个页面以满足您的商店需求。在本篇博文中,我们将介绍如何在Magento 2中自定义首页页面。

    步骤 1:登录到Magento 2后台管理区域
    使用管理员凭据登录到您的Magento 2后台管理区域。

    步骤 2:创建自定义首页布局文件
    在Magento的主题中,找到用于首页的布局文件。通常,首页的布局文件位于以下路径:`app/design/frontend/{Vendor}/{Theme}/Magento_Theme/layout/default.xml`。如果您使用的是自定义主题,请相应地修改路径。

    步骤 3:编辑自定义首页布局文件
    打开自定义首页布局文件,并根据您的需求进行编辑。您可以使用XML标签和属性来定义页面的结构、内容和布局。

    以下是一些常见的自定义首页布局设置示例:

    - 增加静态块:您可以使用`<referenceContainer>`标签和`<block>`标签来插入静态块到首页。您可以在适当的位置添加以下代码来插入静态块:

    ```xml
    <referenceContainer name="content">
    <block class="Magento\Cms\Block\Block" name="your_block_name">
    <arguments>
    <argument name="block_id" xsi:type="string">your_block_identifier</argument>
    </arguments>
    </block>
    </referenceContainer>
    ```

    将`your_block_name`替换为您给定的静态块名称,将`your_block_identifier`替换为静态块的标识符。

    - 调整页面布局:您可以使用不同的容器名称和块标签来调整页面布局。通过在布局文件中的适当位置添加或修改容器和块标签,您可以重新排列页面的各个部分,如页眉、页脚、侧边栏等。

    步骤 4:保存并清除缓存
    保存并关闭自定义首页布局文件。然后,登录到Magento后台管理区域,导航到“系统” > “缓存管理”,并清除页面缓存,以便使更改生效。

    步骤 5:查看自定义的首页页面
    现在,打开Magento商店的首页,您将看到您的自定义布局和修改已成功应用于首页页面。

    通过自定义Magento 2的首页页面,您可以完全控制首页的布局、内容和呈现方式,以提供独特而个性化的用户体验。

    ]]>
    Fri, 17 Nov 2023 03:57:20 +0000
    <![CDATA[在Magento 2中添加CMS页面的步骤和说明]]> https://www.360magento.com/blog/magento2-add-cms-page/

    ---

    在Magento 2中,CMS页面允许您创建和管理自定义内容,如关于我们、联系我们、常见问题等页面。本篇博文将介绍在Magento 2中添加CMS页面的详细步骤和说明。

    步骤 1:登录到Magento 2后台管理区域
    在您的浏览器中打开Magento 2后台管理页面,并使用管理员凭据登录到您的商店。

    步骤 2:导航到CMS页面管理
    导航到左侧菜单中的“内容” > “页面”下的“页面”选项。这将打开CMS页面管理区域。

    步骤 3:创建新CMS页面
    点击“创建新页面”按钮,开始创建新的CMS页面。

    步骤 4:填写CMS页面信息
    在创建CMS页面的编辑界面,您需要填写以下信息:
    - 标题:输入CMS页面的标题。这是显示在前端页面上的页面名称。
    - 标识符:输入CMS页面的唯一标识符。这将用于生成CMS页面的URL。
    - 页面布局:选择页面布局。您可以选择全宽布局或左右侧边栏布局,具体取决于您的设计需求。
    - 激活:选择是否激活该CMS页面。
    - 排序:指定CMS页面的排序顺序。

    步骤 5:编辑CMS页面内容
    在“内容”选项卡下,您可以使用WYSIWYG编辑器输入和格式化CMS页面的内容。您可以添加文本、图像、链接和其他元素来定制页面。

    步骤 6:保存并发布CMS页面
    完成CMS页面内容编辑后,点击右上角的“保存并发布”按钮,保存并发布CMS页面。您的CMS页面现在已经创建成功并可在前端页面上访问。

    步骤 7:查看CMS页面
    要查看新添加的CMS页面,您可以导航到前端页面,并在导航菜单或链接中找到相应的CMS页面。

    这些是在Magento 2中添加CMS页面的基本步骤和说明。通过创建自定义的CMS页面,您可以灵活地管理和展示内容,以满足您的商店需求。

    ]]>
    Thu, 16 Nov 2023 07:11:10 +0000
    <![CDATA[在Magento 2中添加CMS块的步骤和说明]]> https://www.360magento.com/blog/magento2-add-cms-block/ 在Magento 2中,CMS块是可重复使用的内容片段,可以在多个页面和布局中使用。本篇博文将介绍在Magento 2中添加CMS块的详细步骤和说明。

    步骤 1:登录到Magento 2后台管理区域
    在您的浏览器中打开Magento 2后台管理页面,并使用管理员凭据登录到您的商店。

    步骤 2:导航到CMS块管理
    导航到左侧菜单中的“内容” > “块”下的“块”选项。这将打开CMS块管理区域。

    步骤 3:创建新CMS块
    点击“创建新块”按钮,开始创建新的CMS块。

    步骤 4:填写CMS块信息
    在创建CMS块的编辑界面,您需要填写以下信息:
    - 标识符:输入CMS块的唯一标识符。这将用于在页面或布局中调用CMS块。
    - 标题:输入CMS块的标题。这是显示在后台管理区域中的标识块的名称。
    - 激活:选择是否激活该CMS块。

    步骤 5:编辑CMS块内容
    在“内容”选项卡下,您可以使用WYSIWYG编辑器输入和格式化CMS块的内容。您可以添加文本、图像、链接和其他元素来定制块。

    步骤 6:保存并发布CMS块
    完成CMS块内容编辑后,点击右上角的“保存并发布”按钮,保存并发布CMS块。您的CMS块现在已经创建成功并可在页面和布局中使用。

    步骤 7:调用CMS块
    要在页面或布局中调用CMS块,您可以使用以下代码:
    ```

    ```
    将`YOUR_BLOCK_IDENTIFIER`替换为您之前创建的CMS块的标识符。

    步骤 8:保存并更新页面或布局
    在调用CMS块的页面或布局中,点击右上角的“保存”按钮,保存并更新页面或布局。这将使CMS块在前端页面上显示。

    这些是在Magento 2中添加CMS块的基本步骤和说明。通过创建和使用CMS块,您可以轻松地重复使用和管理内容片段,提高网站的灵活性和可维护性。

    ]]>
    Thu, 16 Nov 2023 03:13:59 +0000
    <![CDATA[探索Magento 2的电商优势]]> https://www.360magento.com/blog/magento2-ecommerce-advantages/ Magento 2是一款功能强大的开源电子商务平台,为在线商家提供了许多优势和功能。在本篇博文中,我们将探索Magento 2作为电子商务系统的一些主要优势。

    1. 强大的扩展性:Magento 2提供了广泛的扩展和定制选项,使商家能够根据自己的需求和业务模型来定制和扩展其电子商务平台。通过丰富的市场和开发者社区,商家可以轻松地添加新功能、集成第三方服务和扩展其在线业务。

    2. 灵活和可定制的设计:Magento 2提供了丰富的主题和布局选项,使商家能够根据自己的品牌形象和目标受众来设计独特和个性化的在线商店。商家可以轻松地更改颜色、字体、布局和其他设计元素,以创建具有吸引力和专业性的电子商务界面。

    3. 强大的商品管理功能:Magento 2提供了全面的商品管理功能,包括库存管理、商品属性、产品类型和价格规则等。商家可以轻松地管理大量商品,设置不同的产品选项和价格策略,并使用灵活的目录结构来组织商品。

    4. 多语言和多货币支持:作为一个全球化的电子商务平台,Magento 2支持多语言和多货币。商家可以轻松地创建多语言站点,并为不同地区的客户提供本地化的购物体验。多货币功能使商家能够在不同国家和地区接受多种货币的支付。

    5. 强大的营销和促销工具:Magento 2提供了各种营销和促销工具,帮助商家吸引和留住客户。商家可以设置特价商品、优惠券、购物车价格规则等,以提供个性化和有吸引力的购物体验,并增加销售和转化率。

    6. 高级搜索和过滤功能:Magento 2具有强大的搜索和过滤功能,使客户能够快速找到他们想要的商品。商家可以配置高级搜索引擎、设置筛选器和排序选项,提供优化的商品浏览和购物体验。

    综上所述,Magento 2作为一款先进的电子商务系统,为商家提供了强大的功能和灵活性,能够满足各种在线商务需求。无论是中小型企业还是大型企业,Magento 2都为其提供了一个可靠和可扩展的电子商务平台。

    ]]>
    Wed, 15 Nov 2023 07:04:48 +0000
    <![CDATA[成为一名出色的Magento前端开发人员所需的知识和技能]]> https://www.360magento.com/blog/magento-frontend-developer-skills/

    作为一名Magento前端开发人员,需要具备一系列的知识和技能,以便在开发过程中能够高效地创建出色的用户界面和用户体验。在本篇博文中,我们将探讨成为一名出色的Magento前端开发人员所需的关键知识和技能。

    1. HTML、CSS和JavaScript:作为前端开发人员,掌握HTML、CSS和JavaScript是基础中的基础。深入了解HTML标记、CSS样式和JavaScript交互能力,能够构建具有良好结构、样式和交互的网页。

    2. Magento主题开发:了解Magento的主题开发是成为一名优秀的Magento前端开发人员的关键。熟悉Magento主题的结构和层次结构,能够创建自定义主题、定制样式和布局,并应用到Magento商店中。

    3. 响应式设计和移动优化:在移动设备使用的普及下,响应式设计和移动优化变得至关重要。具备响应式设计和移动优化的技能,能够确保Magento商店在各种设备上都能提供出色的用户体验。

    4. 前端框架和库:掌握流行的前端框架和库,例如Bootstrap、jQuery等,能够使用这些工具来加速开发过程、提高效率,并实现更复杂的交互效果。

    5. Sass或Less等CSS预处理器:使用CSS预处理器能够提供更灵活和可维护的CSS代码。熟悉Sass、Less等CSS预处理器,能够使用变量、嵌套规则和混合等功能,简化CSS开发并提高代码的可重用性。

    6. 版本控制系统:熟悉版本控制系统,例如Git,能够有效地管理和追踪代码更改。掌握版本控制系统的基本操作和工作流程,能够与团队协作,并轻松地回溯和管理代码版本。

    7. 网页性能优化:优化Magento商店的网页性能对于提供卓越的用户体验至关重要。了解前端性能优化的最佳实践,如减少HTTP请求、压缩和合并资源、使用缓存等技术,能够提高Magento商店的加载速度和响应性。

    8. 调试和故障排除:作为一名前端开发人员,需要具备调试和故障排除的技能。能够使用浏览器开发者工具、日志和其他调试工具,快速定位和解决前端问题。

    综上所述,成为一名出色的Magento前端开发人员需要掌握HTML、CSS和JavaScript等基础知识,具备Magento主题开发、响应式设计和移动优化等技能,并熟悉前端框架、CSS预处理器和网页性能优化等工具和技术。

    ]]>
    Wed, 15 Nov 2023 03:07:50 +0000
    <![CDATA[在Magento程序中记录日志并保存在var/log目录]]> https://www.360magento.com/blog/logging-in-magento-ultimate-guide/ 在Magento开发中,记录日志是一种有用的方式来跟踪和调试应用程序中的问题。本文将提供一份详细的指南,教您如何在Magento程序中使用代码记录日志,并将日志保存在var/log目录中,以便轻松地管理和分析日志信息。

    步骤1:创建日志记录器实例
    首先,在您的Magento程序中,您需要创建一个日志记录器实例。您可以使用Magento的内置日志记录器类`\Psr\Log\LoggerInterface`来实现这一点。可以在您的类构造函数或需要记录日志的方法中注入该日志记录器实例。

    use Psr\Log\LoggerInterface;
    
    class YourClass
    {
        protected $logger;
    
        public function __construct(LoggerInterface $logger)
        {
            $this->logger = $logger;
        }
    
        // ...
    }

    步骤2:记录日志消息
    一旦您有了日志记录器实例,您可以使用该实例记录日志消息。`LoggerInterface`接口提供了几个常用的日志级别,例如`debug`、`info`、`warning`和`error`。您可以根据需要选择适当的级别。

    // 在您的方法中记录日志
    public function yourMethod()
    {
        // ...
    
        $this->logger->debug('This is a debug message.');
        $this->logger->info('This is an info message.');
        $this->logger->warning('This is a warning message.');
        $this->logger->error('This is an error message.');
    
        // ...
    }
    

    步骤3:配置日志保存路径

    默认情况下,Magento将日志保存在var/log目录下。确保该目录具有适当的写入权限,以便Magento可以在其中创建和写入日志文件。

    步骤4:查看和管理日志
    记录的日志将保存在var/log目录中的不同日志文件中。您可以使用SSH或FTP等工具,访问Magento安装目录下的var/log目录,以查看和管理生成的日志文件。根据需要,您可以在开发或调试过程中定期检查日志文件,以获取有关应用程序运行状况和潜在问题的详细信息。

    结束语
    通过按照上述步骤,在Magento程序中记录日志并将其保存在var/log目录中,您将能够轻松地跟踪和调试应用程序中的问题。日志记录是开发过程中的重要工具,可以帮助您定位和解决潜在的错误和异常情况。希望本篇指南对Magento程序中的日志记录有所帮助!

    ]]>
    Tue, 14 Nov 2023 08:00:00 +0000
    <![CDATA[Magento电商网站购物车流程详细指南]]> https://www.360magento.com/blog/magento-ecommerce-shopping-cart-guide/ 购物车是电商网站中至关重要的一环,为用户提供了方便的购物体验和订单管理。本文将为您提供一份详细的指南,介绍Magento电商网站的购物车流程,从添加商品到结算订单的完整过程,帮助您了解和优化购物车流程,提升用户的购物体验。

    步骤1:商品浏览和选择
    用户首先浏览Magento电商网站上的商品列表,可以通过分类、搜索或推荐等方式找到感兴趣的商品。用户可以查看商品详情、价格、库存情况和其他相关信息,并选择要购买的商品。

    步骤2:添加商品到购物车
    一旦用户决定购买商品,他们可以将商品添加到购物车。在商品页面上,通常有一个"加入购物车"按钮,用户点击后,商品将被添加到购物车中。

    步骤3:购物车页面
    添加商品到购物车后,用户会被重定向到购物车页面,展示他们添加的商品列表。在购物车页面上,用户可以查看每个商品的详细信息,如名称、价格、数量和小计。用户可以修改商品数量、移除商品或清空整个购物车。

    步骤4:结算流程
    当用户完成商品选择并准备结算时,他们可以点击"结算"按钮,进入结算流程。在这一步骤中,Magento网站通常要求用户登录或创建一个新账户。用户需要提供相关信息,如收货地址、付款方式和配送方式。

    步骤5:订单确认
    在结算流程的最后一步,用户将被导向订单确认页面。在此页面上,用户可以再次检查订单的详细信息,包括商品列表、收货地址、付款方式和配送方式。用户可以确认订单细节,并选择提交订单。

    步骤6:订单完成
    一旦用户提交订单,Magento电商网站会生成订单号并显示订单确认页面。用户可以在订单确认页面上查看订单摘要和详细信息,并收到订单确认的电子邮件通知。此时,用户可以选择继续购物或返回网站主页。

    结束语
    购物车流程是Magento电商网站中至关重要的一环,对用户的购物体验和订单管理起着关键作用。通过本文提供的详细指南,您可以了解Magento购物车流程的各个步骤,并通过优化和改进购物车流程来提升用户的购物体验。希望本篇指南对Magento电商网站的购物车流程有所帮助!

    ]]>
    Tue, 14 Nov 2023 03:04:22 +0000
    <![CDATA[成为一名优秀的Magento开发人员所需的关键技能]]> https://www.360magento.com/blog/skills-magento-developer/ 导语:Magento是一种广泛使用的电子商务平台,作为一名Magento开发人员,掌握关键技能至关重要。本文将详细介绍成为一名优秀的Magento开发人员所需的关键技能,帮助您迈向成功的Magento开发之路。

    1. 熟悉PHP编程语言:
      作为Magento的主要开发语言,对PHP的熟悉程度对于成功开发和定制Magento非常重要。掌握PHP的基本语法、面向对象编程(OOP)和相关的设计模式是必不可少的。

    2. Magento架构的理解:
      深入了解Magento的架构和工作原理对于开发定制模块和主题至关重要。掌握Magento的模块结构、数据库架构、事件系统和前端技术栈(如布局、块和模板)是非常重要的。

    3. Magento扩展和模块开发:
      熟悉Magento扩展和模块开发是成为一名优秀Magento开发人员的关键。了解如何创建自定义模块、添加新功能、覆盖现有功能和扩展Magento的核心功能是必备技能。

    4. 前端开发技能:
      熟悉HTML、CSS和JavaScript等前端技术,以及流行的前端框架(如Bootstrap)是非常有帮助的。这将使您能够定制Magento的前端样式和布局,提供出色的用户体验。

    5. 数据库管理:
      熟悉MySQL或其他关系型数据库管理系统对于在Magento中处理数据非常重要。了解数据库设计、查询优化和索引的基本原理是必要的。

    6. 版本控制和团队协作:
      掌握版本控制工具(如Git)和团队协作工具(如GitHub或Bitbucket)是必备技能。这将使您能够有效地管理代码、合作开发和进行版本控制。

    7. 问题排查和调试能力:
      成为一名优秀的Magento开发人员需要具备良好的问题排查和调试能力。熟悉使用调试工具、查看错误日志和分析代码以解决问题是必要的技能。

    8. 学习和自我提升:
      Magento是一个不断发展和更新的平台,作为开发人员,持续学习和自我提升是必须的。掌握新的技术和工具,关注Magento的最新版本和最佳实践将有助于您不断提升技能水平。

    结语:成为一名优秀的Magento开发人员需要综合运用多种技能和知识。通过熟悉PHP编程语言、深入了解Magento架构、掌握扩展开发和前端技术、熟悉数据库管理等关键技能,您将能够在Magento开发领域脱颖而出。同时,不断学习和自我提升是不可或缺的,以跟上Magento平台的发展和最新技术趋势。希望本文对您成为一名优秀的Magento开发人员有所帮助。

    ]]>
    Mon, 13 Nov 2023 07:46:12 +0000
    <![CDATA[如何导入Magento的产品和图片]]> https://www.360magento.com/blog/how-to-import-products-and-images-in-magento/ 在Magento中导入产品和图片是建立和管理电子商务网站的重要任务。本文将提供一份详尽的指南,帮助您了解如何顺利导入产品和图片到Magento平台,并确保产品数据和图片正确关联,以提供出色的购物体验。

    步骤1:准备产品和图片数据
    首先,准备好产品和图片数据。确保产品数据以CSV或Excel文件的形式保存,其中包含产品的详细信息,如名称、描述、价格、SKU等。同时,收集产品图片并确保每个产品的图片与其对应的信息匹配。

    步骤2:登录到Magento后台管理面板
    使用管理员凭据登录到Magento的后台管理面板。确保您具备导入产品和管理目录的权限。

    步骤3:导入产品数据
    在Magento后台管理面板的左侧导航栏中,选择"System",然后选择"Import"。在导入页面中,切换到"Products"选项卡,并点击"Choose File"按钮,选择包含产品数据的CSV或Excel文件。

    步骤4:配置产品导入设置
    在导入页面中,您可以配置各种产品导入设置。确保正确地映射CSV/Excel文件中的每个列与Magento的相应产品属性。您还可以设置其他选项,如处理重复产品、更新现有产品等。

    步骤5:导入产品
    配置完毕后,点击"Check Data"按钮,确保产品数据符合预期。如果没有错误,点击"Import"按钮开始导入产品数据。在导入过程中,系统将显示进度和结果。

    步骤6:导入产品图片
    在导入产品数据后,您需要导入相应的产品图片。将产品图片上传到Magento的媒体库,并将其与相应的产品关联。在Magento后台管理面板的左侧导航栏中,选择"Products",然后选择"Catalog"。找到要导入图片的产品,并编辑每个产品的详细信息。在"Images and Videos"选项卡下,上传产品图片并设置其顺序和类型。

    步骤7:保存和更新产品
    在完成产品和图片导入后,确保点击保存并更新每个产品的信息。这将确保产品和图片正确关联和显示。

    结束语
    通过按照上述步骤,您可以顺利地将产品和图片导入到Magento平台,并确保它们正确关联和显示。这样,您将为您的电子商务网站提供丰富的产品信息和吸引人的图片,提升用户的购物体验。请记住,在进行任何导入之前,建议在测试环境中进行实验,以确保导入过程不会影响您的实际网站。希望本篇指南对您的Magento产品和图片导入过程有所帮助!

    ]]>
    Mon, 13 Nov 2023 03:54:28 +0000
    <![CDATA[提高Magento外贸网站运行速度的关键措施]]> https://www.360magento.com/blog/key-measures-to-improve-operating-speed-of-magento-foreign-trade-websites/ 导语:在竞争激烈的外贸市场中,一个快速响应的网站对于吸引客户和提升销售至关重要。然而,许多Magento外贸网站可能存在速度较慢的问题,影响用户体验和搜索引擎排名。本文将分享一些权威的专业技巧,帮助您提高Magento外贸网站的运行速度,以获得更好的业务结果。

    1. 优化图像和媒体文件:
    - 压缩和优化网站上的图像和媒体文件,以减少其文件大小并提高加载速度。
    - 使用适当的图像格式(如JPEG、PNG)并设置适当的压缩级别。

    2. 使用缓存和CDN:
    - 配置Magento的缓存系统,包括页面缓存、对象缓存和数据库查询缓存。
    - 使用内容分发网络(CDN)将网站内容分发到全球各地的服务器,加快用户访问速度。

    3. 压缩和合并CSS和JavaScript文件:
    - 压缩CSS和JavaScript文件,以减少其文件大小。
    - 合并多个CSS和JavaScript文件,减少HTTP请求的数量。

    4. 使用优化的主题和扩展:
    - 选择优化的Magento主题和扩展,确保其代码质量和性能优化。
    - 定期检查和更新主题和扩展,以确保其与最新版本的Magento兼容。

    5. 延迟加载和异步加载内容:
    - 使用延迟加载技术加载页面上的图片、视频和其他资源,以减少初始页面加载时间。
    - 将非关键的内容(如社交媒体插件)异步加载,确保页面的主要内容优先加载。

    6. 优化数据库:
    - 定期清理Magento数据库中的无用数据,如日志、临时表等。
    - 优化数据库查询,包括创建索引、删除重复数据等。

    7. 使用高速托管和服务器优化:
    - 将Magento网站托管在高速和可靠的服务器上,确保服务器响应时间快。
    - 配置服务器缓存和压缩,以提高网站性能。

    8. 前端优化:
    - 最小化HTTP请求,减少页面加载时间。
    - 使用浏览器缓存和Gzip压缩,提高页面加载速度。

    结语:通过采取以上关键措施,您可以显著提高Magento外贸网站的运行速度,提升用户体验和搜索引擎可见性。请记住,优化网站速度是一个持续的过程,建议定期进行测试和优化,以确保网站始终处于最佳状态。作为一个专业的外贸网站,快速响应和流畅的用户体验将为您赢得更多的客户和业务机会。

    ]]>
    Sun, 12 Nov 2023 07:38:10 +0000
    <![CDATA[如何启用Magento的页面缓存功能以提升网站速度]]> https://www.360magento.com/blog/enable-magento-page-caching/ Magento是一个功能强大的电子商务平台,为了提高网站速度和性能,启用页面缓存功能是至关重要的。本文将详细介绍如何在Magento中启用页面缓存功能,以加快网站加载速度并提升用户体验。

    步骤1:登录Magento后台管理面板
    首先,使用管理员凭据登录到Magento的后台管理面板。在成功登录后,您将进入控制面板,准备进行页面缓存的配置。

    步骤2:进入配置页面
    在控制面板中,点击左上角的"Stores"(商店)选项卡,然后选择"Configuration"(配置)。

    步骤3:打开缓存配置
    在左侧导航栏中,找到并展开"Advanced"(高级)选项。然后,点击"System"(系统)下的"Cache Management"(缓存管理)。

    步骤4:启用页面缓存
    在缓存管理页面中,您将看到各种缓存选项。找到"Full Page Cache"(完整页面缓存)并确保其状态为"Enabled"(已启用)。

    步骤5:保存配置更改点击页面右上方的"Save Config"(保存配置)按钮,将您的更改保存到Magento配置中。

    步骤6:清除缓存启用页面缓存后,您需要清除现有的缓存以使更改生效。点击页面右上方的"Flush Magento Cache"(清除Magento缓存)按钮,然后确认清除操作。

    步骤7:测试页面缓存现在,您的Magento网站已经启用了页面缓存功能。为了确保缓存正常工作,您可以打开您的网站并浏览几个页面。注意观察页面加载速度的改善。

    结语:通过启用Magento的页面缓存功能,您可以显著提升网站的加载速度和性能。这将改善用户体验、提高转化率,并有助于提升搜索引擎排名。记得定期清除缓存以确保最新的数据和内容被缓存。

    优化网站速度是一个持续的过程,建议您定期进行测试和优化,以确保网站保持最佳状态。希望本文对您启用Magento页面缓存功能有所帮助。

    ]]>
    Sun, 12 Nov 2023 03:39:48 +0000
    <![CDATA[使用Magento构建强大的电子商务网站的亮点]]> https://www.360magento.com/blog/highlights-of-building-powerful-ecommerce-sites-with-magento/ 在当今数字化时代,拥有一个优秀的电子商务网站对于企业的成功至关重要。作为一种功能强大的电子商务平台,Magento为企业提供了一个全面而灵活的解决方案。本文将介绍使用Magento构建强大的电子商务网站的优势和关键功能。

    1. 强大的功能和灵活性:
      Magento提供了丰富的功能和灵活的架构,使企业能够构建适应其业务需求的定制化网站。无论是中小型企业还是大型企业,Magento都可以根据需求进行扩展和定制,满足各种电子商务业务模型。

    2. 多店铺管理:
      Magento允许通过单个后台管理多个在线商店。这对于拥有多个品牌、产品线或地理位置的企业来说非常有用。通过统一的管理界面,您可以轻松地管理和监控各个店铺的库存、订单、支付和运输等。

    3. 丰富的扩展和集成:
      Magento提供了一个庞大的扩展市场,您可以通过集成各种插件和模块来增强您的网站功能。无论是支付网关、物流服务、市场营销工具还是客户支持系统,Magento都有相应的扩展可供选择。

    4. 灵活的主题和设计:
      Magento提供了丰富的主题和模板选择,使您能够根据品牌形象和用户体验需求来定制网站的外观和用户界面。您可以选择现有主题或进行定制开发,以实现独特的品牌风格和用户友好的设计。

    5. 强大的营销和SEO功能:
      Magento内置了一系列强大的营销工具,包括促销活动、优惠券、产品推荐和客户分群等。此外,Magento还具有友好的搜索引擎优化(SEO)功能,有助于提高网站在搜索引擎中的可见性和排名。

    6. 安全和可靠性:
      Magento提供了一系列安全性功能和措施,以确保网站和用户数据的安全。它具有强大的身份验证、加密和防范欺诈的功能,保护您的网站免受潜在的安全威胁。

    总而言之,使用Magento构建电子商务网站是一个明智的选择。其强大的功能、灵活性和可扩展性使企业能够打造出符合业务需求的出色网站。无论您是中小型企业还是大型企业,Magento都提供了一套完整的解决方案,帮助您实现在线销售的成功。开始使用Magento,为您的电子商务业务开辟一个新的篇章吧!

    ]]>
    Sat, 11 Nov 2023 07:30:07 +0000
    <![CDATA[Magento有哪些适用于中小型企业的定制化功能?]]> https://www.360magento.com/blog/customizable-features-of-magento-suitable-for-smes/ 导语:构建一个强大而灵活的电子商务网站对于中小型企业来说至关重要。而Magento作为一款功能强大的电子商务平台,为企业提供了全面的解决方案。本文将为您介绍如何利用Magento的定制化功能,为中小型企业打造一个令人印象深刻的在线销售平台。无论是个性化设计、促销活动还是客户管理,Magento都能满足您的需求,助力您实现电子商务的成功。让我们一起探索Magento的定制化功能,为您的企业开辟新的商机!

    Magento提供了许多适用于中小型企业的定制化功能,以下是其中一些主要功能:

    1. 主题和布局定制:Magento允许中小型企业根据自身品牌形象和用户需求进行网站主题和布局的定制。您可以选择现有的主题,进行自定义调整,或者进行定制开发以满足特定的设计要求。

    2. 商品管理:中小型企业可以使用Magento的商品管理功能来管理产品目录、库存和价格。您可以轻松添加、编辑和删除产品,并设置不同的属性和选项。

    3. 促销和优惠券:Magento提供了灵活的促销工具,中小型企业可以使用这些工具来创建各种促销活动和优惠券。您可以设置折扣、特价商品、买一送一等促销策略,以吸引和激励客户购买。

    4. 客户管理:通过Magento的客户管理功能,中小型企业可以管理客户信息、订单历史和购物车内容。您可以查看和跟踪客户活动,为客户提供个性化的服务和推荐。

    5. 支付和物流集成:中小型企业可以通过Magento集成各种支付网关和物流服务,以提供方便的支付和快速的配送选项。您可以选择适合您业务的支付解决方案,并与物流服务商合作,提供灵活的配送选择。

    6. 多语言和多货币支持:如果您的中小型企业面向国际市场,Magento提供了多语言和多货币支持的功能。您可以轻松地创建多语言版本的网站,并根据不同地区的货币设置定价和支付选项。

    7. 数据分析和报告:通过Magento的数据分析和报告功能,中小型企业可以获取关键的业务指标和销售数据。您可以监控网站流量、销售趋势和客户行为,以便做出战略决策和优化业务运营。

    这些功能只是Magento提供给中小型企业的一小部分定制化功能。通过灵活的架构和丰富的扩展市场,企业可以根据自身需求进行更多的定制化开发,满足特定的业务需求。

    ]]>
    Sat, 11 Nov 2023 03:32:44 +0000
    <![CDATA[Magento 2的发展前景:持续创新与市场机遇]]> https://www.360magento.com/blog/magento-2-continued-innovation-and-market-opportunities/ 导语:Magento 2作为一款强大而灵活的电商平台,一直以来都备受关注。在本文中,我们将探讨Magento 2的发展前景,包括其持续创新、市场机遇以及为企业带来的价值。

    1. 持续创新与功能增强

    Magento 2在推出以来一直致力于持续创新和功能增强。相对于Magento 1,Magento 2引入了一系列的改进和新功能,包括更强大的性能、更直观的后台管理界面、更好的移动端支持等。这些改进使得Magento 2成为一个更现代化、更易用的电商平台,能够帮助企业满足不断变化的市场需求。

    2. 强大的生态系统和扩展库

    Magento 2拥有一个庞大而活跃的生态系统,包括开发者、合作伙伴和社区。这个生态系统为Magento 2提供了丰富的扩展和集成选项,使得企业能够根据自身需求定制和扩展他们的电商平台。无论是支付网关、物流集成还是营销工具,都能够在Magento 2的扩展库中找到适合的解决方案。

    3. 响应式设计和移动优化

    随着移动互联网的普及,移动端的重要性不言而喻。Magento 2具备响应式设计和移动优化的特点,能够自适应不同屏幕尺寸,并提供出色的移动购物体验。这使得企业能够更好地满足消费者的移动购物需求,提高转化率和用户满意度。

    4. 全球化和多语言支持

    Magento 2具备全球化的能力,支持多语言和多货币。这使得企业能够轻松扩展到不同的国家和地区,拓展全球市场。无论是本地化的内容、价格还是支付方式,Magento 2都提供了强大的工具和功能,帮助企业实现全球化战略。

    5. 企业级功能和可扩展性

    Magento 2是一款强大的企业级电商平台,适用于各种规模和行业的企业。它提供了丰富的功能和可扩展性,能够满足复杂的业务需求。无论是B2C还是B2B电商,Magento 2都能够提供强大的功能和灵活的定制选项,支持企业实现增长和创新。

    结论:

    总体而言,Magento 2具备强大的发展前景。它不仅在技术上持续创新和改进,还能够满足企业的多样化需求。随着电商市场的不断发展和竞争的加剧,有一个可靠、灵活的电商平台是企业成功的关键。Magento 2通过其强大的功能、扩展库和全球化支持,成为许多企业的首选。无论是新兴企业还是已有企业的升级,选择Magento 2都能够为他们带来成功和增长的机会。因此,我们可以乐观地预见Magento 2在未来的市场中将继续保持领先地位,为企业带来持续的价值和竞争优势。

    ]]>
    Fri, 10 Nov 2023 07:36:07 +0000
    <![CDATA[Magento的发展历程:在当今电商领域的优势与突破]]> https://www.360magento.com/blog/evolution-magento-advantages-current-ecommerce-landscape/ 导语:
    Magento作为一款知名的电子商务平台,在当前的电商领域中展现出了许多独特的优势。本文将为您详细介绍Magento的发展历程,并探讨它在当今社会电商领域的优势和突破。

    1. 创立与初期发展
      Magento于2007年由Roy Rubin和Yoav Kutner共同创立。他们致力于打造一款灵活、可扩展的电子商务平台,以满足不断变化的市场需求。Magento的创立标志着一个全新的电商时代的开始。

    2. 功能丰富与可定制性
      Magento以其丰富的功能和可定制性而闻名。它提供了强大的产品目录管理、安全的支付网关、订单处理和客户关系管理等功能。商家可以根据自身需求对Magento进行定制,打造独特的在线购物体验。

    3. 开源优势
      作为一款开源平台,Magento具有开放的架构和源代码。这使得开发者可以根据自己的需求对平台进行自由的扩展和定制。开源的特性使得Magento拥有庞大的开发者社区,为商家提供了丰富的资源和支持。

    4. 可扩展性与性能
      随着电商行业的快速发展,可扩展性和性能成为了一个关键因素。Magento凭借其可扩展的架构和强大的性能,能够处理大规模的产品目录、高订单量和高流量的网站访问。即使在高峰期,Magento也能保持稳定的运行,为用户提供无缝的购物体验。

    5. 移动端和全渠道能力
      在移动互联时代,移动端的重要性不可忽视。Magento提供了响应式设计和移动友好的功能,确保了在不同设备上的无缝购物体验。此外,Magento还提供了全渠道能力,商家可以将线上商店与实体零售店、在线市场和社交媒体平台进行整合,为用户提供统一和一致的品牌体验。

    结论:
    Magento在电商领域的发展历程令人瞩目。其功能丰富的平台、可扩展性、开源灵活性以及活跃的社区支持使其成为商家建立强大在线存在的首选。通过充分利用Magento的优势,商家可以打造引人入胜的在线商店,适应不断变化的市场需求,并在当今竞争激烈的电商领域蓬勃发展。

    ]]>
    Fri, 10 Nov 2023 02:54:58 +0000
    <![CDATA[如何启用和优化Magento的缓存功能,提升网站性能]]> https://www.360magento.com/blog/how-do-i-enable-and-optimize-magento-caching/ 导语:Magento的缓存功能是提高网站性能和用户体验的重要工具。本文将介绍如何启用和优化Magento的缓存功能,以加快网站加载速度并提升性能。

    Magento是一款功能强大的电子商务平台,但由于其复杂性,网站性能可能会受到影响。启用和优化Magento的缓存功能可以缓解这个问题,并提供更快的页面加载速度和更好的用户体验。下面是一些步骤和技巧,帮助您启用和优化Magento的缓存功能。

    1. 启用Magento的缓存功能:

    - 登录到Magento后台管理面板。
    - 在侧边栏菜单中,选择"商店"(Store)> "设置"(Configuration)。
    - 在左侧菜单中,找到并点击"高级"(Advanced)> "系统"(System)。
    - 在"缓存管理器"(Cache Management)部分,您将看到各种缓存类型的列表。
    - 选择您想要启用的缓存类型,如页面缓存(Page Cache)、块缓存(Block Cache)、对象缓存(Object Cache)等。
    - 对于每种选择的缓存类型,使用下拉菜单选择"启用"(Enable)。
    - 点击"提交"(Submit)按钮以保存更改。

    2. 优化Magento缓存的设置:

    - 精细调整缓存类型:根据您的网站需求,选择启用适当的缓存类型。页面缓存(Page Cache)适用于不经常更改的页面,而块缓存(Block Cache)适用于经常重复的页面元素。对象缓存(Object Cache)则用于存储数据库查询结果。
    - 清除缓存:在进行更改之后,务必清除缓存以确保更改生效。在Magento后台的"缓存管理器"页面中,您可以选择清除整个缓存或仅清除特定缓存类型。
    - 定期刷新缓存:设置Magento的缓存刷新时间,以确保缓存内容始终保持最新。通过定期刷新缓存,您可以在不影响网站性能的情况下更新内容。

    3. 配置页面缓存:

    - 使用Varnish缓存:Varnish是一个流行的反向代理缓存服务器,可以显著提高Magento网站的性能。通过配置Magento和Varnish之间的集成,您可以实现高速的页面缓存,减少服务器负载和网络延迟。
    - 配置CDN(内容分发网络):使用CDN来分发Magento网站的静态资源,如图像、CSS和JavaScript文件。CDN能够将这些资源缓存在全球各地的服务器上,从而加速资源加载速度。

    通过启用和优化Magento的缓存功能,您可以显著提高网站的性能和用户体验。确保定期清除缓存、刷新缓存并根据网站需求进行适当的缓存类型选择。结合其他性能优化策略,如压缩图像、合并CSS和JavaScript文件等,您将创建一个快速、高效的Magento网站,为访问者提供卓越的用户体验。

    ]]>
    Thu, 09 Nov 2023 07:31:45 +0000
    <![CDATA[Magento站点技巧和对手分析方法:提升电商竞争力的关键]]> https://www.360magento.com/blog/magento-site-tips-and-adversary-analysis-methods/ 导语:在竞争激烈的电商市场中,建立一个成功的Magento站点需要掌握一些关键的技巧,并且了解对手分析的方法。本文将为您介绍一些提升Magento站点竞争力的技巧,并分享有效的对手分析方法。

    一、Magento站点技巧:

    1. 优化网站速度:网站速度直接影响用户体验和搜索引擎排名。优化图片大小、使用缓存技术、压缩文件等方法可以显著提高网站的加载速度。

    2. 响应式设计:确保您的Magento站点具有响应式设计,能够适应不同设备的屏幕尺寸。这将提供良好的移动用户体验,并有助于提高搜索引擎排名。

    3. 简化结账流程:简化结账流程可减少购物车放弃率,提高转化率。通过减少步骤、提供多种支付选项和优化表单填写等方式,使结账过程更加便捷和用户友好。

    4. 强化产品页面:优化产品页面的布局、描述和图片,确保清晰的产品信息和吸引人的展示效果。添加用户评价和社交分享功能,增加用户参与度和信任度。

    5. SEO优化:对Magento站点进行关键词研究,并在标题、描述、URL和内容中合理地应用。创建有价值的内容和外部链接,提高搜索引擎的可见性和排名。

    二、对手分析方法:

    1. 竞争对手识别:确定您的主要竞争对手,这些对手在目标市场上与您竞争相似的产品或服务。

    2. 网站分析:分析竞争对手的网站结构、设计和功能。注意他们的用户体验、页面加载速度、购物流程等关键因素。

    3. 关键词研究:研究竞争对手在搜索引擎上的关键词排名和搜索量。确定他们的关键词策略,并找到可以与之竞争的关键词。

    4. 社交媒体分析:了解竞争对手在社交媒体上的活动和影响力。分析他们的社交媒体策略、受众互动和内容推广方式。

    5. 价格和促销策略:了解竞争对手的定价策略和促销活动。分析他们的价格优势、销售策略和客户忠诚度计划。

    6. 用户反馈和评价:查看竞争对手的用户反馈和评价,了解他们的优点和不足之处。从中吸取经验教训,并改进您的Magento站点。

    结论:

    通过掌握Magento站点的关键技巧和对手分析方法,您可以提升电商竞争力并实现业务增长。优化网站速度、响应式设计、简化结账流程、强化产品页面和SEO优化都是提升Magento站点的关键技巧。同时,通过竞争对手的分析,您可以了解他们的策略和优势,并从中汲取经验教训。记住,持续的优化和创新是保持竞争优势的关键,将这些技巧和对手分析方法应用于您的Magento站点,将为您带来更多的成功和增长机会。

    ]]>
    Thu, 09 Nov 2023 03:47:57 +0000
    <![CDATA[关于Magento网站优化的实用技巧]]> https://www.360magento.com/blog/Practical_tips_on_Magento_website_optimization/ 标题:提升Magento网站性能和用户体验的实用技巧

    导语:优化Magento网站是提高性能、加速加载时间和提升用户体验的关键。在本文中,我们将分享一些实用的技巧和建议,帮助您提升Magento网站的性能和用户体验。

    1. 优化网站速度

    网站速度是用户体验的重要因素。以下是一些优化网站速度的技巧:

    - 使用缓存:启用Magento的缓存功能,包括页面缓存、块缓存和对象缓存,以减少页面加载时间。
    - 压缩图像:使用适当的图像压缩工具来减小图像文件的大小,以加快页面加载速度。
    - 合并和压缩CSS和JavaScript:将多个CSS和JavaScript文件合并为较少的文件,并使用压缩工具减小文件大小。
    - 使用CDN:使用内容分发网络(CDN)来分发网站的静态资源,以加快资源加载速度。

    2. 优化网站结构

    优化网站结构可以提高用户体验和搜索引擎的索引能力:

    - 优化URL结构:使用有意义的、描述性的URL,包含关键词,并避免使用过长或复杂的URL。
    - 良好的网站导航:设计清晰的网站导航结构,使用户能够轻松浏览和导航网站的不同部分。
    - 改善内部链接:使用相关的内部链接将页面连接起来,以提高用户体验和搜索引擎的索引能力。

    3. 优化网站内容

    优化网站内容有助于提高搜索引擎可见性和用户体验:

    - 关键词研究:进行关键词研究,了解您的目标受众在搜索引擎上使用的关键词,并将其应用到网站的元标记、标题和内容中。
    - 内容优化:编写高质量、有用且相关的内容,符合SEO最佳实践,并包含目标关键词。
    - 使用标签和标题:为每个页面使用恰当的标题标签(H1、H2等)和页面描述,以提高搜索引擎可读性和用户体验。

    4. 优化网站安全性

    确保Magento网站的安全性对于保护用户数据和信任度至关重要:

    - 更新Magento版本:及时更新Magento版本以获取最新的安全补丁和功能改进。
    - 强密码和访问控制:使用强密码保护Magento后台,并限制对敏感文件和目录的访问权限。
    - 使用SSL证书:为网站启用SSL证书,以加密访问并增加用户信任度。

    5. 监控和优化

    定期监控和优化Magento网站是持续提高性能和用户体验的关键:

    - 网站分析:使用网站分析工具(如Google Analytics)来监控网站性能、用户行为和流量来源,以做出优化决策。
    - 错误日志和性能监控:定期检查Magento的错误日志和性能监控工具,以寻找潜在的问题并及时解决。

    结语

    通过遵循这些实用技巧和建议,您可以提升Magento网站的性能、用户体验和搜索引擎可见性。记住,优化是一个持续的过程,不断监控和改进是确保网站持续优化的关键。让我们一起努力,打造出卓越的Magento网站吧!

    ]]>
    Wed, 08 Nov 2023 07:26:49 +0000
    <![CDATA[Magento开发人员的实用性技巧和方案:提高效率与质量]]> https://www.360magento.com/blog/practical-tips-for-magento-developers/

    作为Magento开发人员,提高开发效率和代码质量是至关重要的。在本文中,我们将分享一些实用的技巧和方案,帮助您更高效地开发Magento站点,并提供高质量的代码和功能。

    1. 使用代码版本控制
    使用Git或其他代码版本控制工具来管理您的Magento项目代码。通过版本控制,您可以轻松跟踪代码更改、回滚错误和协作开发。这样可以提高代码管理和团队协作的效率。

    2. 自定义模块开发
    遵循Magento的模块化开发原则,将自定义功能封装为模块。这样可以保持代码的可维护性和可扩展性,并避免直接修改核心文件。模块化的开发方式使得代码修改和更新更加灵活和可控。

    3. 使用事件和观察者
    利用Magento的事件和观察者模式,以松耦合的方式扩展和修改Magento的功能。通过触发和监听事件,可以在不修改核心代码的情况下实现自定义逻辑。这样可以提高代码的可维护性和可扩展性。

    4. 数据库迁移和更新
    使用Magento的数据库迁移工具(如Magento 2的Schema和Data Patch)来管理数据库的变更和更新。这样可以跟踪和应用数据库变更,并确保在不同环境之间的一致性。数据库迁移工具可以提高开发团队的协作效率和代码质量。

    5. 优化数据库查询
    在编写自定义查询时,遵循Magento的最佳实践,使用索引、缓存和合理的查询语句来优化数据库查询。避免在循环中执行查询,而是尽可能使用集合操作。优化数据库查询可以提高Magento站点的性能和响应速度。

    6. 使用代码生成器
    Magento提供了代码生成器工具(如命令行工具和代码模板),可以加快开发速度。使用这些工具可以自动生成常见的代码结构和文件,减少手动编写的重复工作。代码生成器可以节省时间并提高代码的一致性和规范性。

    7. 测试和调试
    编写单元测试和集成测试来验证您的代码的正确性。使用调试工具和日志记录来排查和解决问题。通过测试和调试,可以提高代码的质量和稳定性,减少潜在的错误和问题。

    8. 安全性和性能优化
    遵循Magento的安全性和性能优化指南,确保您的代码和配置符合最佳实践。保护网站免受潜在的安全漏洞,并实施性能优化措施,如缓存、CDN集成和代码优化。安全性和性能优化是确保Magento站点稳定和高效运行的关键。

    9. 持续集成和部署
    使用自动化工具和流程来实现持续集成和部署。通过自动构建、测试和部署代码,可以减少人工操作和减少错误。持续集成和部署可以提高开发团队的效率和代码交付的质量。

    总结:
    通过应用这些实用的技巧和方案,您可以提高Magento开发的效率和质量。代码版本控制、模块化开发、事件和观察者模式、数据库迁移、优化查询、代码生成器、测试和调试、安全性和性能优化,以及持续集成和部署等方法都能帮助您更好地管理和开发Magento站点。这些实践将帮助您节省时间、减少错误,并提供稳定高效的Magento站点。始终记住,不断学习和探索新的技术和最佳实践,以跟上Magento的发展和提高您的开发技能。祝您在Magento开发中取得成功!

    ]]>
    Wed, 08 Nov 2023 03:00:00 +0000
    <![CDATA[选择Magento作为您的电子商务网站:优势和好处]]> https://www.360magento.com/blog/choosing-magento-for-your-ecommerce-website/ 了解 Magento

    Magento是一个功能强大且功能丰富的开源电子商务平台,使企业能够创建和管理在线商店。它提供了一个灵活且可定制的框架,用于构建具有许多特性和功能的电子商务网站。 

    Magento采用PHP开发,提供可伸缩性、可扩展性以及丰富的插件和主题生态系统,使其成为各种规模的企业建立和发展在线业务的热门选择。

    Magento 的两个版本是Magento Open SourceMagento Commerce这些版本满足不同的需求和业务要求,提供不同级别的功能、支持、可扩展性等。

    Magento 开源与 Magento 商务

    Magento 开源 

    Magento 开源提供强大的电子商务功能,包括产品目录管理、购物车功能、结帐选项、支付网关集成、SEO 优化等。它还支持多商店和多语言功能,适合中小型企业。

    Magento 商务 

    Magento Commerce 包含 Magento 开源的所有功能。尽管如此,它还引入了先进的功能,例如个性化购物体验、客户细分、先进的营销工具、B2B 商务功能、增强的搜索功能等等。这些功能旨在满足具有更复杂电子商务需求的大型企业。

    Magento 开源

    作为一个开源版本,Magento 开源受益于提供支持、扩展和更新的开发人员和贡献者社区。

    Magento 商务

    Magento Commerce 提供专门的技术支持、安全更新和性能优化。对于需要在线商店保持一致的正常运行时间和可靠性的企业来说,这种级别的支持非常重要。

    当您看到 Magento Open sourse 和 Magento Commerce 之间的根本区别时,您可以选择最适合您的需求、预算和增长愿望的版本。 

    但是,如果您对哪个版本适合您的业务感到困惑,您可以从Magento 开发公司获得帮助。他们将分析您的业务和您的需求。之后,他们会建议最合适的选择。可以节省大量资源和时间。 

    选择合适的公司后,您可以从他们那里获得高度可定制和可扩展的电子商务商店。因此,如果您对Magento 版本感到困惑,请向他们寻求帮助。

    此外,让我们看看使用两个版本的 Magento 电子商务网站构建器框架为您的企业带来的好处。 

    Magento 的优点:-

    以下是使用 Magento 框架为像您这样的企业开发电子商务商店的一些主要好处。 

    #1:可扩展性 

    可扩展性对于确保在线商店能够容纳不断增长的客户、产品和交易而不会减慢或崩溃至关重要。凭借其可扩展的架构和性能优化功能,Magento 能够很好地处理大型产品目录和高流量网站。

    它支持批量产品导入、可配置产品和分层导航等功能,使企业能够有效地管理和展示广泛的产品范围。其缓存机制和优化技术也确保即使在流量高峰期也能保证流畅的用户体验。

    Magento 采用模块化和分层架构,将不同的组件和功能分开。这使得企业能够根据需要扩展系统的各个部分,例如数据库服务器、应用程序服务器和缓存机制。

    此外,它还支持多种缓存机制,例如全页缓存和对象缓存,可显着提高网站性能并减少服务器负载,使平台能够处理更高的流量。

    #2:灵活性

    Magento 提供了大量的自定义选项。您可以修改前端设计、创建自定义主题并实施独特的功能,以使在线商店与其品牌标识和客户期望保持一致。

    扩展:- Magento 市场提供了广泛的扩展和插件,可以集成到平台中以增强功能。这些扩展涵盖了支付网关、运输方式、营销工具等领域。

    此外,Magento 支持 API 和集成框架,允许与 ERP、CRM 和库存管理工具等第三方系统无缝连接。这使企业能够构建定制的工作流程并自动化各种流程。

    Magento 的架构允许在单个安装中创建多个商店。这对于管理多个品牌或迎合不同市场的企业来说是有益的,因为它可以集中管理,同时允许每个商店拥有独特的品牌和产品分类。

    #3:广泛的功能

    Magento 提供了一组广泛的内置功能,使电子商务企业能够创建全面且功能丰富的在线商店。这些功能涵盖电子商务生命周期的各个方面。 

    例如,产品管理有助于管理产品属性、变体、自定义选项、产品详细信息、图像、类别、折扣和特别优惠。其次,库存控制功能提供了实时监控和管理库存水平、处理低库存产品通知、延期交货和库存产品以及仓库管理系统的灵活性。

    管理中的订单处理功能也使订单处理和管理更加有效。借助 Magento,电子商务商店所有者可以增强客户体验。您可以提供个性化的购物体验,另外实施具有保存的地址和订单历史记录的用户帐户,启用访客结账或注册选项等。

    此外,庞大的第三方扩展和主题市场丰富了 Magento 的生态系统这些扩展可以轻松集成到平台中,以增强功能并提高在线商店的美观度。

    #4:移动响应式设计

    越来越多的消费者使用移动设备在线浏览和购物。移动设备已成为许多人访问互联网的主要方式。

    移动响应式设计可确保网站或在线商店在各种设备和屏幕尺寸(包括智能手机、平板电脑和台式机)上正确显示和运行。Magento 非常重视移动响应式设计,为用户提供无缝的购物体验,无论他们使用什么设备。

    Magento 提供固有的移动响应式设计功能,使在线商店能够适应不同的屏幕尺寸和方向。Magento 移动响应式设计的一些关键功能包括灵活的布局、触摸友好的界面、优化的图像、响应式菜单、用户友好的表单和性能优化。 

    #5:SEO 友好

    Magento的架构和功能旨在支持SEO,确保在该平台上构建的在线商店可以轻松地被搜索引擎发现,并在搜索结果中获得更高的排名。

    Magento 的代码库结构良好并遵循最佳实践,使搜索引擎机器人可以更轻松地导航和索引网站内容。它允许用户为产品页面、类别和内容页面创建 SEO 友好的 URL。这些 URL 可以定制为用户可读且搜索引擎友好的。此外,它还提供产品和页面自定义过程的简单元标题和元描述,以便您可以在搜索引擎结果中创建相关片段。

    此外,Magento 的架构和功能在设计时考虑了 SEO,为企业提供了创建 SEO 友好的在线商店所需的工具和实践。利用 Magento 的功能并实施有效的 SEO 策略最终会提高转化率和销售额。

    #6:多语言和多货币支持

    全球市场提供的客户群比单一国内市场大得多。针对来自不同国家的客户可以让企业开拓新的收入来源并最大限度地发挥其增长潜力。

    Magento 的国际化能力使企业能够通过提供多语言内容和多货币选项来瞄准全球受众。该功能集对于旨在扩大业务范围和服务客户​​的电子商务企业来说非常宝贵。 

    使用 Magento,您可以创建多个商店视图,每个视图都有其相关的语言、内容和产品信息。借助 Milt 货币支持,Magento 使客户能够查看产品价格并以当地货币完成交易。兑换率可以手动设置或与实时汇率数据集成,以确保为国际客户提供准确的定价。

    #7:强大的安全性

    Magento 非常重视安全性,以确保保护客户数据、敏感信息和在线交易。它与各种安全支付网关集成,确保客户支付数据在交易过程中得到加密和安全传输。

    通过 PCI DSS 和数据加密,它可以保护电子商务商店的内部数据。强大的用户身份验证机制(包括密码策略和多因素身份验证)有助于防止未经授权访问管理面板和客户帐户。

    Magento 定期发布安全补丁和更新以解决已知漏洞。我们鼓励商家及时应用这些更新,以保护他们的商店。

    除此之外,扩展安全、管理安全、监控和入侵检测使像您这样的在线商家更加安全。

    #8:社区支持

    Magento 社区由开发人员、设计师、商人和爱好者组成,他们积极参与讨论、论坛和知识共享平台。社区成员提供协助、分享最佳实践并解决问题,使商家更轻松地找到解决方案并优化他们的商店。

    Magento 社区论坛等平台使用户能够发布问题、寻求建议和分享经验。经验丰富的社区成员经常提供有价值的见解和解决方案。社区成员经常创建教程、指南和文章来帮助其他人理解和掌握该平台的不同方面。

    此外,许多第三方开发人员向 Magento Marketplace 贡献免费和付费扩展和主题,扩展了该平台的功能和自定义选项。此外,Magento 社区成员还组织活动、会议和聚会,以促进交流、学习和协作。

    ]]>
    Tue, 07 Nov 2023 08:37:28 +0000
    <![CDATA[Magento 产品推荐:优点和技巧]]> https://www.360magento.com/blog/magento-product-recommendations/ Magento 产品推荐是什么?

    Magento 产品推荐是一个帮助在目录中的产品页面上显示相关产品的工具。它们可以与某个商品相关,或者只是与它一起购买,这会产生相当诱人的报价。

    因此,这些建议会促使您的客户购买更多产品并探索更多产品。鉴于您将某些产品放在客户眼前,这也可能会导致冲动购买。

    借助 Magento 产品推荐引擎,一个产品页面可以包含多个项目。相应地,这会给您带来许多好处。

    产品推荐的好处

    由于我们已经知道 Magento 2 产品推荐是什么,因此了解这些产品块如何使您的商店受益是合乎逻辑的。那么,让我们来看看此功能的一些主要优点。

    1.平均订单价值(AOV)的增加

    精心挑选的产品推荐巧妙地鼓励您的客户购买更多产品。因此,当顾客购买额外的商品以及他们打算购买的商品时,订单总数就会增加。如果该策略运行得足够好,您可以看到平均订单价值整体上的增长。

    2. 销售和转化率改善

    从长远来看,AOV 的增加会带来销售额和转化率的提高。客户可以使用更多商品,从而浏览您的网站并更多地与您的商店互动。因此,您有机会降低购物车放弃率,并将闲置访客转变为买家。 

    3.交叉销售和追加销售

    每家商店都有一个比其他商店表现更好的产品。可悲的是,仍然有一些商品卖得不好。Magento 2 产品推荐可以完美地消除此类情况。它们可以让您推广表现较差的产品,并让它们更容易被发现。

    4. 增强客户体验

    最后,使用产品推荐对您和您的客户都有好处。如果你能满足客户的需求,他们在做出选择时可能会感到更自由。因此,您可以通过适量的个性化营销活动极大地改善客户的体验。

    ]]>
    Mon, 06 Nov 2023 07:42:37 +0000
    <![CDATA[如何在 Magento 2 中设置联系我们表单的电子邮件 ID]]> https://www.360magento.com/blog/setup-email-id-for-contact-us-form-in-magento-2/ 启用 Magento 2 联系我们表格的步骤

    第1步:登录您的商店后台并进入管理面板,选择商店 > 设置 > 配置

    步骤 2:展开配置并选择  常规部分下的联系人然后转到联系我们设置。

    步骤 3:确保取消选中“使用系统值”。默认情况下,要启用“联系我们”,该值将为“是”以激活联系我们线路。

    步骤 4:转到电子邮件选项部分。

    • 发送电子邮件至:您需要在此处输入管理员电子邮件或您希望接收联系我们查询的电子邮件。
    • 电子邮件发件人:选择您希望看到的商店发件人作为电子邮件发件人。
    • 电子邮件模板:从现有模板中选择电子邮件模板,或从下拉菜单中选择默认模板选项。
    ]]>
    Sun, 05 Nov 2023 07:16:24 +0000
    <![CDATA[如何在 Magento 2 的发票、发货和贷项凭证 PDF 中显示/隐藏订单 ID]]> https://www.360magento.com/blog/show-hide-order-id-in-invoice-shipment-credit-memo-pdf-of-magento-2/ 众所周知,Magento 是构建电子商务网站的强大 CMS 之一。它提供了许多预加载的功能,为此,您无需编写一行代码,只需在 Magento 2 后端中设置一些配置即可启用这些功能。
    很多时候,当您的客户在您的 Magento 2 商店下订单时,他们会收到大量附有订单电子邮件的文档。到时候他们就很难找到哪个文档与哪个订单相关了?原因 Magento 不会在 Magento 2 的发票、发货和贷项凭证 PDF 标题的顶部显示订单 ID。这可能会让您的客户感到困惑。但是,您可以在上述所有 Magento 生成的文档上显示订单 ID,而无需编写任何代码。想知道如何正确?嗯,Magento 2 后端预加载了一个配置,您只需启用它就可以了!

    转到 Store –> Configuration -> Sales –> PDF Printouts

    默认情况下,所有这些配置都设置为“是”,但如果您想隐藏订单 ID,只需从下拉列表中选择“否”将其关闭。

    ]]>
    Sat, 04 Nov 2023 08:10:10 +0000
    <![CDATA[什么是基础货币以及如何在 Magento 2 中设置货币选项]]> https://www.360magento.com/blog/what-is-base-currency-and-how-to-set-currency-options-in-your-magento/ 电子商务是增长最快的技术型业务,许多成熟企业正在走向全球。因此,在向其他国家推出之前设置货币设置已成为每个电子商务商店的首要任务。

    Magento 2 作为电子商务平台在世界各地广泛使用。它具有默认功能,可以为全球多达 200 个国家/地区设置货币。您可以设置要在产品价格、订单和发票中显示的货币符号。管理员可以自定义货币符号的外观。

    将会有来自不同国家的商家利用 Magento 的力量来建立他们的电子商务商店。商家来自不同的国家,因此您可能需要当地货币作为主要货币,如果您不从事国际业务,则您的商店必须只需要启用当地货币。

    如果您从事国际业务,那么您可能已经在 Magento 2 商店中设置了多网站或多商店视图,以使您的商店全球化。在这种情况下,您需要设置不同国家/地区的货币,例如,对于印度,您需要 INR,对于英国,您可以启用 GBP,对于美国和世界其他地区,假设您想要美国。所有这些都可以使用默认的 Magento 功能进行配置,甚至无需一行代码。

    导航到Store >Configuration >General >Currency Setup >Currency Options,

    基础货币:基础货币用于所有在线支付交易。基础货币范围由目录价格范围定义(“目录”>“价格”>“目录价格范围”)。

    默认显示货币:默认显示货币是您要为商店设置的默认货币,如果您的商店仅限于您所在的国家/地区,则您可以设置自己的货币并保存。例如,对于印度商店,我们将在此字段中选择印度卢比。

    如果您有国际业务、多商店视图或多网站设置,则需要根据商店选择相应的货币。例如,印度商店为印度卢比,英国商店为英镑,美国和世界其他地区为美元。

    允许的货币:当您开展国际业务并在全球范围内销售产品时,您将需要提供多种货币可供选择。如果客户有能力更改货币,他将获得更多信任,或者您可以允许全球接受的货币,例如美元和英镑。

    无论您在此处选择哪种货币,这些货币都将在前端可供客户选择。在下面的示例中,我启用了美元和欧元。

    ]]>
    Fri, 03 Nov 2023 07:06:09 +0000
    <![CDATA[如何更改 Magento 2 中的 Favicon 图像]]> https://www.360magento.com/blog/how-to-change-the-favicon-image-in-magento-2/ 今天,我们将学习如何更改默认 Magento 2 中的 favicon(图标)。我不需要告诉你太多关于 favicon 是什么,但如果我必须简短介绍它,那么让我告诉你它就是与站点标题一起出现在浏览器选项卡顶部的图标。在某些浏览器中,它还可能出现在 URL 旁边。

    它本质上代表了您的网站,因此根据您的需要设置或更改网站图标非常重要。一些网络服务和搜索引擎也可能使用该图标。默认情况下,Magento 有很多功能可供您使用。这个简单的教程将帮助您如何自行更改网站图标。Favicon 图标的大小应为 12 x 12 或 32 x 32。它应该是 .ico 格式。

    按照下面描述的步骤更改 Magento 2 商店的图标。

    1. 登录到您的管理面板
    2. 选择菜单Content  Configuration  Select Your Theme  Edit

    3. 找到 HTML Head 部分

    4. 您将看到一个上传图标的选项,点击上传并在此处上传您的图标。
    5. 保存配置
    ]]>
    Thu, 02 Nov 2023 07:45:54 +0000
    <![CDATA[如何在 Magento 2 中按产品 ID 和 SKU 加载产品?]]> https://www.360magento.com/blog/load-products-by-id-and-sku-in-magento/ 如何借助 Magento 推荐的一些简单代码从产品 ID 和 SKU 加载产品。

    让我们首先看看如何从产品 ID 加载产品。

    方法 – 1: Magento 不推荐使用这种简短的方法,因此我们也不使用。

    方法 - 2:当您需要产品信息时,Magento 强烈推荐使用此方法。

    现在,我们来看看如何按产品SKU加载产品。

    方法 – 1: Magento 不推荐使用这种简短的方法,因此我们也不使用。

    方法 - 2:当您需要产品信息时,Magento 强烈推荐使用此方法。

    所以,现在就这样了。使用这些代码,您将能够按 ID 或 SKU 加载产品信息。

    ]]>
    Wed, 01 Nov 2023 07:44:23 +0000
    <![CDATA[如何删除 Magento 2 中不必要的客户帐户链接]]> https://www.360magento.com/blog/remove-customer-account-navigation-links-magento-2/ 如何删除 Magento 2 中不必要的客户帐户链接

    Magento 默认情况下会在客户帐户页面上显示大量客户帐户链接列表。如果您的业务与其他业务不同,并且不支持新闻通讯订阅,那么在客户帐户页面显示的链接列表中就没有必要。而且很多时候需要自定义所有默认链接,因为对于客户帐户页面上显示的所有链接没有具体要求。有一些要求可以删除一些对客户来说不必要的链接。

    在下面的客户帐户屏幕上显示 Magento 2 默认提供的链接列表: 

    • My Orders
    • My Downloadable Products
    • Account Dashboard
    • Newsletter Subscriptions
    • Stored Payment Methods
    • Address Book
    • Account Information
    • Billing Agreements
    • My Wish List
    • My Product Reviews

    如何删除导航链接的步骤

    第 1 步:首先,创建自定义扩展或主题并覆盖客户布局文件

    创建扩展并覆盖布局 XML 文件

    app/design/frontend/[命名空间]/[主题]/Magento_Customer/layout/customer_account.xml

    第 2 步:使用标签从我的帐户中删除任何额外的链接。

       <!-- Remove unwanted account navigation links -->

       <!-- Put this file in: app/design/frontend/[Namespace]/[Theme]/Magento_Customer/layout/customer_account.xml -->

       <!-- Store credit -->

       <referenceBlock name="customer-account-navigation-customer-balance-link" remove="true"/>

       <!-- Downloadable product link -->

       <referenceBlock name="customer-account-navigation-downloadable-products-link" remove="true"/>

       <!-- Subscription link -->

       <referenceBlock name="customer-account-navigation-newsletter-subscriptions-link" remove="true"/>

       <!-- Billing agreement link -->

       <referenceBlock name="customer-account-navigation-billing-agreements-link" remove="true"/>

       <!-- Product review link -->

       <referenceBlock name="customer-account-navigation-product-reviews-link" remove="true"/>

       <!-- My credit card link -->

       <referenceBlock name="customer-account-navigation-my-credit-cards-link" remove="true"/>

       <!-- Account link -->

       <referenceBlock name="customer-account-navigation-account-link" remove="true"/>

       <!-- Account edit link -->

       <referenceBlock name="customer-account-navigation-account-edit-link" remove="true"/>

       <!-- Address link -->

       <referenceBlock name="customer-account-navigation-address-link" remove="true"/>

       <!-- Orders link -->

       <referenceBlock name="customer-account-navigation-orders-link" remove="true"/>

       <!-- Wish list link -->

       <referenceBlock name="customer-account-navigation-wish-list-link" remove="true"/>

       <!-- Gift card link -->

       <referenceBlock name="customer-account-navigation-gift-card-link" remove="true"/>

       <!-- Order by SKU -->

       <referenceBlock name="customer-account-navigation-checkout-sku-link" remove="true"/>

       <!-- Gift registry -->

       <referenceBlock name="customer-account-navigation-giftregistry-link" remove="true"/>

       <!-- Reward points -->

       <referenceBlock name="customer-account-navigation-reward-link" remove="true"/>

    第 3 步:现在,只需清除缓存并验证“我的帐户”页面上的链接将被删除。

    ]]>
    Tue, 31 Oct 2023 07:45:48 +0000
    <![CDATA[如何在 Magento 2 中安装主题]]> https://www.360magento.com/blog/install-theme-in-magento-2/ 在 Magento 2 中配置安装主题的步骤:

    下载主题

    下载您选择的 Magento 2 主题,该主题将以压缩形式提供。下载主题后,请解压下载的主题,您将得到两个文件夹,即 App 和 Pub。

    上传主题

    完成上述步骤后,只需导航到您的商店并将 App 和 Pub 文件夹上传到 Magento 2 商店的根目录。

    运行命令

    现在,使用 SSH 连接您的 Magento 2 商店并导航到 Magento 2 商店的根目录。

    然后运行以下给出的升级命令:

    php bin/magento setup:upgrade

    执行上述步骤后,运行以下给出的命令来部署静态内容:

    php bin/magento setup:static-content:deploy

    应用主题

    现在,转到管理面板并导航到Content → Configuration ,如下面的屏幕截图所示。

    现在单击编辑按钮,如下面的屏幕截图所示

    从下拉列表中选择您上传的主题,然后单击保存配置,如下面的屏幕截图所示。

     

    从下拉列表中选择您上传的主题,然后单击保存配置,如下面的屏幕截图所示。

    执行完上述简单步骤后,您可以访问应用主题的网站。

     

    ]]>
    Mon, 30 Oct 2023 07:38:26 +0000
    <![CDATA[如何解决Magento 2 索引过程中的问题]]> https://www.360magento.com/blog/unlock-reindex-process-in-magento-2/ 在 Magento 2 中重新索引的步骤:

    第 1 步:索引锁定时重新索引

    运行以下命令来重新索引:

    您会发现库存流程被跳过,如下所示

    第 2 步:获取索引类型信息

    首先,您必须查看 Magento 2 的索引类型列表,然后运行以下命令:

    运行该命令后,您将得到以下输出:

    步骤 3:检查索引类型状态

    现在通过运行下面给出的命令检查所有索引类型的状态:

    运行该命令后,您将得到以下输出:

    步骤 4: 重置索引类型

    为了解决这个问题,您必须重置在给定命令下运行的锁定索引类型:

    要重置多个索引类型,请运行以下命令:

    这里只有一种索引类型被锁定,因此我们将运行以下给出的命令:

    运行上述命令后的输出将类似于:

    第 5 步:重新索引索引类型 

    您必须再次检查索引器状态,因此再次运行以下命令:

    运行上述命令后的输出将是:

    ]]>
    Thu, 23 Aug 2018 08:01:39 +0000
    <![CDATA[常见的Magento SSL配置问题解决方法]]> https://www.360magento.com/blog/magento-ssl-issues/

    安全套接字层(SSL)已成为电子商务网站的一个重要方面。SSL确保客户与网站之间的双向通信在整个交易期间保持安全。

    使用SSL保护网站表明网站所有者非常重视保护客户的个人信息。就SERP(搜索引擎结果页面)的标准而言,拥有SSL的网站排名越来越高。

    安装和维护SSL证书可能是网站所有者的麻烦。如果处理不当,该问题可能严重妨碍访客的体验。结果是网站的收入和声誉显著降低。

    使用Magento SSL时,网站所有者应确保:

    • SSL已正确安装
    • 安全URL已设置
    • 安全URL在前端和后端实现
    • SSL证书设置为包括www
    • 网站里没有不安全的链接

    现在将讨论困扰网站的最常见的Magento SSL相关问题。此外,我还将提供解决问题的方法。

    1. Magento SSL无效

    按照以下步骤从Magento后台激活SSL :

    • 导航到 System > Configuration > General > Web
    • 单击"Secure"选项卡
    • 启用"Use Secure URLs in the frontend"选项为"yes"
    • 启用"Use Secure URLs in the Admin" 选项为"yes"
    • 检查offload header为"SSL_OFFLOADED"

    激活Magento SSL后,网站的URL将从"HTTP"  更改为"HTTPS"

    如果问题仍然存在,则问题可能出在数据库层上。请按照以下步骤来解决问题:

    • 选择数据库表"core_config_data"
    • 运行查询:"Select * from core_config_data where path = ‘%web/secure/base_url%’;"
    • 检查列值。如果是"HTTPS",则表示后台设置已完成。

    如果SSL仍无效,则您的网站的SSL设置存在问题。有时,在成功安装和激活SSL后会出现此问题。Ajax调用或第三方URL调用中的问题也可能导致此问题。以下是如何解决这些问题:

    Ajax 调用

    如果Ajax调用中存在任何设置问题,请更改以下代码:

    echo Mage::getUrl(‘MYMODULE/MYCONTROLLER/MYACTION’, array(‘_secure’ => Mage::app()->getStore()->isCurrentlySecure()));

    第三方URL调用

    替换掉不是"https"的第三方URL,比如"HTTPS://www.example.com",替换成"HTTPS://www.example.com"

    2.Magento SSL结账页面重定向

    当Magento SSL无法正常工作时,会出现此问题。在许多情况下,结帐页面会被重定向到其他页面,例如主页或index页面。

    以下是修复结帐重定向问题的过程:

    • 在Magento网站中安装SSL证书。
    • 导航到 Admin > System > Configuration > General > Web
    • 转到"secure settings"并将base URL更改为"HTTPS://"
    • 保持"Base link URL"为“{{secure_base_url}}”
    • 保持Skin, Media, and JavaScript设置为“{{secure_base_url}}skin/etc”
    • 选择“Use Secure URL for frontend”为"yes"
    • 最后,单击"Save"以应用设置。

    以上过程适用于所有Magento版本。

    3.无法获得本地颁发者证书

    若要解决此问题,请按照下列步骤操作:

    • 创建证书到本地副本并将其保存在服务器上的安全位置。
    • 如果您使用的是Linux,请将文件保存在:"/etc/ssl/example_com.crt "
    • 在服务器(以apache为例)中正确配置:
       
      ServerName example.com 
      DocumentRoot /var/www/
      
      SSLEngine on 
      SSLCertificateFile /etc/ssl/example_com.crt 
      SSLCertificateKeyFile /etc/ssl/private/example_com.key 
      SSLCertificateChainFile /etc/ssl/example_com.ca-bundle 
      
    • 根据保存文件的位置更新文件。
    • 最后,重启服务器以更改应用配置。

    4.安装Magento SSL使后台无法访问

    有两种方法可以解决这个问题:

    • 手动将"core_config_data"表中的"web/secure/use_in_adminhtml"值更改为"0";或执行SQL语句"INSERT INTO core_config_data (scope,scope_id,path,value) VALUES ('default',0,'web/secure/use_in_adminhtml',1);"
      • 改回表中的URL为“HTTP://your.domain.com/”

      通过删除“/var/cache”文件清除magento缓存

      5.使用SSL ,magento页面显示404 Page Not Found

      SSL有自己的配置文件,有时当SSL不能正常工作时,它可能会给出404(Page not found)错误。通常,文件如下:

      “sudonano /etc/apache2/sites-available/default-ssl”

      您需要将“AllowOverride None”更改为“AllowOverride All”,然后重新启动服务器。

      sudo /etc/init.d/apache2 restart

      重新启动服务器后,您将看到所有页面都正常工作。如果您收到任何与页面内容相关的错误,请检查页面上的任何外部URL。尝试消除外部URL并仅包含相对URL。

      6.在后台使用Magento SSL时出现403(Forbidden)错误

      在以下情况下,有时会故意返回错误代码403(Forbidden):

      • 用户没有进去特定页面的权限。
      • 用户正在尝试访问已将autoindex设置为off的目录。
      • 用户正在尝试访问只能在内部访问的文件。

      但是,出于本文的目的,我将讨论无意中发生错误的情况。

      权限未正确设置

      这是此问题背后最常见的原因。如果要提供文件,则服务器必须读取并执行文件的分层目录中的权限。例如:

      对于/usr/share/myfiles/image.jpg,服务器应具有/,/ usr,/ usr / share/ usr / share / myfiles的读取和执行权限。如果您不希望看到此错误,则需要对目录使用标准755,对文件使用644。

      您可以使用namei来检查路径的权限:

      f: /var/www/vhosts/example.com
       
      drwxr-xr-x root     root     /
       
      drwxr-xr-x root     rootvar
       
      drwxr-xr-x www-data www-data www
       
      drwxr-xr-x www-data www-datavhosts
       
      drwxr-xr-xmconnectmconnect    example.com

      目录索引尚未正确定义

      标准PHP设置的索引指令是:

      "index index.html index.htm index.php;"

      在上面的示例中,服务器将首先提供index.html,然后是index.htm,最后是index.php。如果找不到所有上述目录或没有响应,则返回403 forbidden错误。

      7. HTTP与Https重复内容问题

      Http和HTTPS被视为单独的端口。但是,搜索引擎会将这两个版本的内容视为重复内容。从SEO的角度来看,这是一个严重的问题。此问题有3中修复方法:

      规范链接元素

      规范链接元素被添加到网页的head标签中:

      <link rel="canonical" href="HTTP://www.domain.com/star-wars/toys/cut-outs/luke-skywalker.html"/>

      这些链接元素突出显示内容的规范位置。因此,当搜索引擎抓取网站时,只有Https版本会显示在搜索结果中。

      为Https提供不同的Robots.txt

      在此解决方案中,您允许搜索引擎抓取网站的HTTPS版本。这是你应该做的:

      • 使用.htaccess提供两个不同的Robots.txt文件。将常规非安全HTTP文件另存为robots.txt,并将安全HTTPS文件另存为robots_ssl.txt
      • htaccess文件中添加一下代码:

      RewriteEngine on
      RewriteCond %{SERVER_PORT} ^443$
      RewriteRule ^robots\.txt$ robots_ssl.txt [L]
      RewriteEngine on
      RewriteCond %{SERVER_PORT} ^443$
      RewriteRule ^robots\.txt$ robots_ssl.txt [L]

      • 这将改写服务robots_ssl.txtrobots.txt的

      元机器人标签

      如果上述两种方法无法解决问题,可以使用Meta Robots标记。此标记允许对页面进行抓爬但不对其编制索引。要使用该标记,以下代码将添加到网页的Head标记中:

      
      <?php
      
      if(isset($_SERVER['HTTPS']) &&strtolower($_SERVER['HTTPS']) == 'on') {
      
      echo''. "\n";
      
      }
      
      ?>
      <?php
       
      if(isset($_SERVER['HTTPS']) &&strtolower($_SERVER['HTTPS']) == 'on') {
       
      echo''. "\n";
       
      }
       
      ?>

      8.在Magento管理区域中启用SSL时的无限重定向循环

      当您在Magento管理面板中打开SSL时,可能会遇到此问题。

      问题可能出在模型app/code/core/Mage/Core/Model/Store.php

      public function isCurrentlySecure()
      
      {  
      
                  if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
      
                  return true;
      
                  }  
      
                  if (Mage::isInstalled()) {
      
                              $secureBaseUrl = Mage::getStoreConfig('web/secure/base_route_url');
      
                              if (!$secureBaseUrl) {
      
                                          return false;
      
                              }  
      
                              $uri = Zend_Uri::factory($secureBaseUrl);
      
                              $isSecure = ($uri->getScheme() == 'HTTPS' ) &&isset($_SERVER['SERVER_PORT']) && ($uri->getPort() == $_SERVER['SERVER_PORT']);
      
                              return $isSecure;
      
                   } else {
      
                              $isSecure = isset($_SERVER['SERVER_PORT']) && (443 == $_SERVER['SERVER_PORT']);
      
                              return $isSecure;
      
                   }  
      
      }
      

      当在"core_config_data"表中没有"web/secure/base_route_url",默认的响应"isCurrentlySecure"总是返回false

      您可以通过添加服务器变量"HTTPS"  值来修复它  。

      如Nginx与PHP-FPM一起使用,将这些行添加到“nginx.conf”:

      fastcgi_param HTTPS on;

      重新加载服务器,一切都应该正常工作。

      9. SSL-HTTPS Magento前端布局问题

      使用HTTPS对工作站点的更改包括:
      在配置中,
      在不安全部分中
      基本URL:删除"HTTP"

      在安全部分
      基本URL:添加"HTTPS"

      然后刷新缓存。

      10.启用Magento SSL后,管理员登录失败

      在Magento Admin中启用SSL后,通常会出现此问题。以下步骤将解决此问题:

      • 进入数据库并进入"core_config_data"表中,  更新"web/secure/use_in_admindata"path中的value为"0"
      • 将"web/secure/use_in_frontend"path中的"value"设置为"0"
      • 通过使用SSH,登录到主机帐户,并运行命令"rm -rf ~/public_html/magento/var/cache"

      使用共享服务器或主机时,需要更改缓存目录。

      如何更改Magento基本URL?

      可以根据网站的要求设置Magento基本URL。要更改基本URL,请登录Magento管理面板,导航到"System > Configuration > Web > Unsecure > Base URL and System > Configuration > Web > Secure > Base URL"

      完成更改后,您需要进入“System > Cache Management”刷新缓存

      如果Magento管理面板无法访问,则需要在数据库中进行更改。登录"phpMyAdmin",导航到"core_config_data"表,改变"web/unsecure/base_url" 和 "web/secure/base_url"中的value值

      要应用更改,请通过删除var/cache目录中的所有内容来刷新Magento中的缓存

      11.结帐时Magento SSL相关警告

      当您使用Magento网站时,结帐过程可能需要多次修复和调试。在测试网页时,请密切关注页眉和页脚中的图像,因为它们可以创建大量问题。

      要解决此问题,您应该使用图像的直接链接,而不是使用参考或源链接。

      (简写图片源链接)

      (接图像源链接)

      这会通知浏览器它应该按照当前区域加载重要的资源。特别是,使用Chrome测试网站,因为它可以检测任何网站中的大多数错误。

      这些是一些常见的Magento SSL相关问题的解决方案。我希望您能够自己应用修复程序而不会出现任何问题。如果您遇到问题,请随时与我们联系。


      经常问的问题

      Q1。什么是SSL?

      SSL表示用于使网站安全的安全套接字层。它应该安装在每个电子商务网站中,以确保用户和网站之间的交易过程安全。

      Q2。SSL完全免费使用吗?

      许多SSL证书提供商对此收费,但是如果您想要免费且可靠的SSL证书,那么请选择Let's Encrypt。

      Q3。什么是Robots.txt?

      您网站的一个文本文件,用于与网络抓取工具和其他网络机器人进行通信,称为Robots.txt。

      ]]> Tue, 21 Aug 2018 08:50:16 +0000 <![CDATA[magento 1和magento2的比较]]> https://www.360magento.com/blog/m1-m2vs/

      概述

      Magento是一个开源的电子商务网站系统,于2008年3月31日推出。包括出色的功能,它使网店所有者几乎可以做任何像类型的网店。Magento 1迅速占据电子商务市场的主导地位,市场份额约为26%(2014年)。但是,安装其他应用程序非常复杂,并且经常遇到许多错误。因此,Magento在2015年升级到2.0版本,这使得更多扩展的安装变得更加容易。Magento 2旨在帮助商家实现目标。它允许商家建立在线销售网站,下载和服务等。此外,让我们与以前的版本进行比较,事实是Magento 2升级了技术,改变了目录结构,架构,后端改进了平台的界面以支持移动版本。借助创新技术,它有助于实现性能和安全功能的改进。

      对照

      1. 表现

      在页面加载速度或查询执行时间上,由于缓存(Varnish)和数据库优化,Magento完全优于竞争对手。这也是许多用户在Magento 1中面临的问题,而在agento 2中的重大改进。

      • Magento 2支持最新版本的PHP(从PHP 5.5x开始),也包括PHP 7。这些版本包括安全修复程序和新增强功能。
      • Magento 2的加载时间比标准版本的加载时间快2到3秒。要加载主页,类别页面和产品页面,即使不使用用户界面缓存,Magento 2也会在不到1.5秒的时间内加载。
      • 页面内容显示得更快。在查看主要内容时,用户无需等待加载整个页面。
      • 在服务端,Magento 2添加了一个模块来清除缓存。因此用户无需像Magento 1那样安装第三方模块。
      • Magento 2最小化并打包Javascript,从而减少客户端请求数。
      • 压缩图像:Magento 2构建工具以直接在服务器上优化图像,而不是像Magento 1手动执行。
      • 使用静态内容改进缓存处理过程。

      2. 管理员

      与Magento 1相比,Magento 2中的管理界面非常直观且用户友好。

      2.1常规管理界面

      管理面板非常易于配置和使用,并包含一个现代且用户友好的界面。它的组织更多,分为主要类别,如销售,产品,客户,营销等。此外,它只需点击主菜单即可查看所有子类别。

      Imgur

      Magento 2的另一个重要特性是网格管理。管理员可以主动隐藏网格中的某些列作为网格订单或网格客户。您还可以从管理页面上的可用列表中选择列。

      Imgur

      2.2 仪表盘

      在新系统中,您可以在一个地方找到基本信息。“仪表盘”页面概述了终身销售,平均订单金额,最后订单,热门搜索条件,查看次数最多的产品,新客户等。它还显示了财务数据,因此您可以查看业务的总体状态。一目了然。

      Imgur

      2.3 管理产品

      创造更多新产品也更简单。新系统将指导您完成一个简单的分步过程。这里的一个突出创新是Magento 2不仅允许管理员上传产品图像,还可以上传该产品的宣传视频。

      Imgur

      2.4 管理订单

      您的订单页面显示商店中所有订单的列表。您可以按“状态”列中的状态对它们进行排序。如果您想批量更新或查看所有待处理订单或处理订单,您可以快速轻松地找到它们。

      您还可以为订单执行某些操作,例如“暂停”,“取消”或“打印订单”。如果您想在电子表格中查看所有订单信息,它还可以通过订单右上角的CSV导出订单。

      订单的订单将以0000000001开头,并为每个后续订单增加至1。这使管理员可以轻松找出您收到的订单号。

      Imgur

      2.5 管理客户

      在Magento 2中,您可以将客户列表视为产品或订单列表,添加/删除列,更改默认视图,导出到CSV文件或执行许多操作,例如删除客户或分配客户组。特别是,如果您想通过电话沟通接收订单,也可以手动添加客户。

      Imgur

      2.6 营销部分

      在“营销”部分,您可以找到Magento 1中用于促销,通信,搜索引擎优化和搜索,用户内容的所有可用工具。

      Imgur

      2.7 内容

      内容管理界面还使用Magento 2的指定网格,它可以帮助您更好地管理您的帖子。这有助于管理员创建更多内容页面,而无需将WordPress或Drupal添加到Magento站点。

      Imgur

      3. 前端

      3.1 Luma主题

      Magento 2中的Luma Theme看起来比Magento 1中的主题更漂亮。

      以下是Magento 1中的主题:

      Imgur

      这是Magento 2中的主题:

      Imgur

      3.2 响应式设计

      通过响应式Web设计,Magento 2使用户可以通过任何计算机或移动设备轻松连接到商店。这是一个很大的优势,因为自2015年4月21日起,Google算法已正式优先考虑适合移动设备的网站。

      这种响应式设计还极大地增强了用户体验。

      3.3 改善结账(6个步骤 - > 2个步骤

      在Magento 2中,支付流程对客户来说变得更加容易和快捷。Magento 2没有采取6个步骤来结账,而是仅通过2个步骤缩短了流程。

      Magento 1包括6个步骤结帐如下:

      Imgur

      Magento 2只需2个步骤即可结账:

      Imgur

      通过分析客户的电子邮件地址,在填写结帐电子邮件时,Magento 2可以自动识别哪些客户已注册或未注册帐户。对于没有帐户的客户,如果他们想在付款成功后立即创建帐户,则在此运输步骤中输入的信息将成为基础。帐户注册过程比以往更直接。

      3.4 Ajax购物车加载

      购物车是一个帮助客户获取有关他们打算快速购买的产品的信息的地方。每次将产品添加到Magento 1中的购物车时,系统都会重新加载页面,从而对其性能产生负面影响。对于脾气暴躁的客户,等待几秒钟就会导致他们放弃购物车。

      Magento 2集成了Ajax购物车加载功能,允许用户快速查看购买的商品,而不是等到整个页面重新加载。这也有助于增强用户体验。如果您销售的是价值较低的产品,或者您的客户经常在购物车中添加更多产品,这是一个您不能忽视的问题。

      4. SEO和安全

      4.1。更好地支持SEO

      SEO是网上商店的关键因素之一; 你永远不会忘记在你的网站上设置SEO。Magento 1.X在搜索引擎优化中遇到了一些缺陷,其中大部分都是在Magento 2开发时修复的.Magento 2的突出SEO功能包括:

      • 重复内容:Magento 2提供Canonical标签以避免重复内容。它位于Stores > Configuration > Catalog > Catalog > Search Engine Optimization
      • XML站点地图:XML站点地图是包含站点所有页面的文件。Magento 2配备了更好的XML图形。要启用XML站点地图,请转到Stores > Settings > Configuration > Catalog > XML Sitemap
      • Alt产品图片:为产品图片添加alt也有助于提升您在搜索引擎上的排名。转到Catalog > Products > select one Product > add Alt in Images and Videos field
      • Robots.txt文件:帮助网站管理员更灵活地允许或不允许搜索引擎(SE)上的机器人为您网站的某个区域编制索引。要修改Magento 2中的Robots.txt,请转到Content > Design > Configuration > Edit one Store > Search Engine Robots
      • 元标题,元描述,元关键字:Magento 2允许管理员为每个产品/类别添加元标记。管理员只需在编辑或添加新产品/类别时输入搜索引擎优化。
      • 搜索友好的URL:启用URL友好的最快方法是转到Stores> Configuration > General > Web > Search Engine Optimization and turn on Use Web Server Rewrites

      注意:如您所知,新手使用Magento 2来实现如何最好地管理SEO是具有挑战性的。因为SEO分散在Magento的不同位置。

      4.2安全

      Magento 2改进了整体架构,尤其是安全性。通过定期更新软件,Magento 2比旧版本更安全。

      使用散列算法(SHA-256)还可以改进密码,从而最大限度地降低暴力攻击和其他安全攻击的风险。

      ]]>
      Thu, 16 Aug 2018 09:57:08 +0000
      <![CDATA[在Magento中实现黏性边栏(悬浮边栏)]]> https://www.360magento.com/blog/sticky-sidebar/ 因为在Magento1上的一个项目激发了我写这篇博客。重要的信息或按钮操作悬浮在电商网站(PC网站和移动网站)中极为重要,他可以提高您的转换率。这篇博客着重讲解magento详细页中将添加购物的选项按钮悬浮在边栏。悬浮边栏的目的是是侧边栏元素始终在视窗口中显示(或者在满足某些条件时)。这是移动产品选项(magento可配置产品的下拉菜单,颜色,尺寸等),添加到购物车按钮或任何其他对您的产品很重要的元素的理想场所。也就是说,您的客户可以自由浏览产品上的所有内容,一旦决定购买产品,“添加到购物车”按钮就显示在眼前等着点击!

      让我们开始在代码中进行更改以启用此功能。为了这篇博文的目的,我创建了一个自定义主题  Alwayly/StickySidebar

      LESS代码

      app/design/frontend/Alwayly/StickySidebar/web/css/source/里面创建_extend.less文件并复制/粘贴下面的代码:

      .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
        .box-tocart .action.tocart {
          width: 100%;
          margin-right: 0;
        }
       
        .sidebar {
          &.fixed {
            position: fixed;
          }
        }
      }

      确保运行Grunt命令来创建符号链接并编译此代码(仅在PC上,它将侧边栏定位为固定元素,并使"添加到购物车"按钮占用全部宽度)。

      XML代码

      app/design/frontend/Alwayly/StickySidebar/Magento_Catalog/layout/ 中创建catalog_product_view.xml,然后复制/粘贴以下代码片段:

      <page layout="2columns-right" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <referenceBlock remove="true" name="catalog.compare.sidebar" />
          <referenceBlock remove="true" name="wishlist_sidebar" />
       
          <move element="product.info" destination="sidebar.additional" />
       
          <referenceContainer name="sidebar.additional">
              <block class="Magento\Framework\View\Element\Template"
                     name="sticky.sidebar.wrapper"
                     template="Magento_Catalog::sticky-sidebar-js.phtml"
                     after="-" />
          </referenceContainer>
      </page>

      这段代码负责以下内容:

      • 将页面布局从一列更改为右栏侧栏的两列
      • 删除使用此页面布局时包含的两个块(比较和愿望清单块)
      • 更改包含产品选项的块的位置并将其添加到侧边栏
      • 添加将用于调用AMD组件的模板文件,以处理悬浮边栏逻辑和计算

      PHTML代码

      app/design/frontend/Alwayly/StickySidebar/Magento_Catalog/templates/中创建sticky-sidebar-js.phtml并复制/粘贴以下代码片段:

      <script type="text/javascript" data-mage-init='{"stickySidebar":{}}'></script>

      RequireJS代码

      app/design/frontend/Alwayly/StickySidebar/内部创建requirejs-config.js并复制/粘贴以下代码片段:

      var config = {
          map: {
              "*": {
                  stickySidebar: "js/sticky-sidebar",
              }
          }
      };

      jQuery代码

      app/design/frontend/Alwayly/StickySidebar/web/js/sticky-sidebar.js中创建sticky-sidebar.js并粘贴以下代码片段:

      define(["jquery", "matchMedia", "domReady!"], function ($, mediaCheck) {
          "use strict";
       
          var sidebar = {};
          var a2c = $(".product-add-form");
          var a2c_mobile_target = $(".product-info-main > .price-box");
          // nodes required to calculate sidebar params: width, left, padding-left
          var page_main = $(".page-main");
          var page_main_w;
          var main = $(".main");
          var main_w;
          // nodes required to calculate sidebar params: top
          var header = $(".page-header");
          var nav = $(".nav-sections");
          var breadcrumbs = $(".breadcrumbs");
          // luma specific css values
          var a2c_mb = parseInt($("#product-addtocart-button").css("margin-bottom"));
          var main_pb = parseInt(main.css("padding-bottom"));
          var tabs_mb = parseInt($(".product.info.detailed").css("margin-bottom"));
       
          sidebar.el = $(".sidebar");
          sidebar.padding_ratio = parseFloat(sidebar.el.css("padding-left")) / page_main.width();
          sidebar.updateHorizontalParams = function () {
              if (sidebar.el.hasClass("fixed")) {
                  page_main_w = parseFloat(page_main.width());
                  main_w = parseFloat(main.width());
       
                  sidebar.width = page_main_w - main_w;
                  sidebar.left = ($(window).width() - page_main_w) / 2 + main_w;
                  sidebar.p_left = parseInt(page_main_w * sidebar.padding_ratio);
       
                  sidebar.el.css({
                      "width": sidebar.width + "px",
                      "left": sidebar.left + "px",
                      "padding-left": sidebar.p_left + "px"
                  });
              }
          };
          sidebar.updateVerticalParams = function () {
              sidebar.height = sidebar.el.height();
       
              var scrolled_from_top = $(window).scrollTop();
              var header_h = header.outerHeight(true) || 0;
              var nav_h = nav.outerHeight(true) || 0;
              var breadcrumbs_h = breadcrumbs.outerHeight(true) || 0;
              var content_h = main.outerHeight(true) || 0;
              var sidebar_limit_top = header_h + nav_h + breadcrumbs_h;
              var sidebar_limit_bottom = sidebar_limit_top + content_h;
              var sidebar_limit_bottom_criteria = scrolled_from_top + sidebar.height + main_pb + a2c_mb - tabs_mb;
       
              if (sidebar_limit_bottom < sidebar_limit_bottom_criteria) {
                  // sidebar should start drifting out of viewport on the top
                  sidebar.top = sidebar_limit_bottom - sidebar_limit_bottom_criteria;
       
                  sidebar.el.css({"top": sidebar.top + "px"});
              } else if (scrolled_from_top > sidebar_limit_top) {
                  // header and breadcrumbs are now above viewport
                  if (!sidebar.el.hasClass("fixed")) {
                      sidebar.el.addClass("fixed");
                      sidebar.updateHorizontalParams();
                  }
                  sidebar.top = 0;
       
                  sidebar.el.css({"top": sidebar.top + "px"});
              } else {
                  sidebar.el.removeClass("fixed").removeAttr("style");
              }
          };
       
          var onResize = function () {
              $(window).on("resize", function () {
                  sidebar.updateHorizontalParams();
              });
          }, onScroll = function () {
              $(window).on("scroll", function () {
                  sidebar.updateVerticalParams();
              });
          }, onInit = function () {
              mediaCheck({
                  media: "(min-width: 768px)",
                  entry: function () {
                      sidebar.el
                          .addClass("fixed")
                          .prepend(a2c.detach());
       
                      sidebar.updateHorizontalParams();
                      sidebar.updateVerticalParams();
       
                      onResize();
                      onScroll();
                  },
                  exit: function () {
                      a2c.detach().insertAfter(a2c_mobile_target);
       
                      sidebar.el
                          .removeClass("fixed")
                          .removeAttr("style");
                  }
              });
          };
       
          onInit();
      });

      下面我为您讲解代码的逻辑:

      • onInit()方法用于初始化逻辑
      • 通过使用matchMedia库,产品选项可以在移动和pc布局之间切换位置(这种元素的分离是必需的,因为在移动设备上,侧边栏将是页脚之前的最后一个元素,并且不会让页面到达页面的下方)。此媒体查询还负责添加(在PC上)或删除(在手机上)CSS类名“fixed
      • 当只在PC上时,JS会计算四个CSS属性(updateHorizo​​ntalParams() - > width,left,padding-left属性,updateVerticalParams() - > top属性)的值。并加载事件监听器(在页面调整大小和页面滚动进行相同的计算)
      • 侧栏的显示可以分为三种不同的状态:
        • 状态#1 - 只要面包屑在视口中可见,侧栏就会相对定位
        • 状态#2 - 一旦面包屑在视口外滚动,侧栏被定位为固定元素并将保持在视口中
          悬浮边栏 - 使边栏固定
        • 状态#3 - 一旦侧栏的底部与内容的底部对齐,侧栏开始在视口外滑动,就像页面的其余部分一样粘滞边栏 - 保持固定,但向上滚动

      此代码已经过优化,可与Luma主题一起使用,因此您可能需要添加/清除此处所述的一些代码。

      ]]>
      Tue, 12 Jun 2018 01:28:38 +0000
      <![CDATA[7种方法让你的Magento 2主题模板速度加快]]> https://www.360magento.com/blog/make-theme-faster/ Magento 2作为功能强大且功能丰富的电子商务平台。它提供了不错的页面加载速度,但在大量定制下可能会非常缓慢。

      部分性能问题可能是一个开发不标准的自定义主题引起的(在这里重声下,magento有两大主题模板市场,一个$89,一个$179,作为技术的我深知两大模板的优劣,总之不要图一时便宜)。一方面,默认的Luma和Blank主题相当快。另一方面,一些定制的主题很慢,可能会让你的网上商店成为一个噩梦。

      我将分享一些技巧来优化Magento2主题模板让他更快。这些小技巧都是经过实践验证的,他们真的很有用。我已经在各个项目中使用它们,以使Magento 2网站有一个不错的页面加载时间速度。

      加快Magento 2主题模板的7个技巧

      1. 切勿在循环中加载Magento模型。
      2. 缩小HTML。
      3. 切勿使用JS捆绑。
      4. 合并和缩小CSS / JS。
      5. 避免CSS / JS框架。
      6. 优化图像。
      7. 尽量减少第三方扩展的数量。

      1.永远不要将Magento模型加载到循环中

      这事儿常常发生。我经常看到这样的PHP代码:

      foreach($ productCollection as $ product){
      
      $ _product = $ productModelFactory-> create() - > load($ product-> getId())
      
      ...。

      您可能会在Magento 2迭代集合的各种list.phtml模板中看到该结构

      我会解释为什么这对性能不好。Magento 2模型负载很重,需要太多时间。再加上集合不断的循环可能会显著减慢站点的速度。

      另外,不需要加载模型,因为一个集合已经具有可能需要的所有数据。所以你最好检查一下你的主题模板文件和重构代码部分是否包含模型循环。

      如何找出要检查的主题模板?使用Magento 2分析器 - 它将显示最慢的代码块。要启用Magento 2分析器,只需将以下代码添加到index.phppub/index.php

      $ _SERVER ['MAGE_PROFILER'] = 1;

      重新加载网站页面,您将在底部看到配置文件跟踪:

      Magento 2探查器跟踪

      研究跟踪,你会看到哪些模板花费时间最多。

      2.缩小HTML

      如果可以缩小页面大小,可以使主题更快。其中一种方法是缩小HTML。
      Magento 2支持开箱即用页面缩小。您可以转至Stores > Configuration > Advanced > Developer > Template Settings > Minify HTML并将其打开(在Magento 2.2+上,此设置仅在开发人员模式下可见):

      在Magento中缩小HTML

      有一点要记住 - 这种配置更改仅适用于生产和默认模式。

      你可能会问 - 这些模式是什么?Magento 2有三种运行模式:default(默认模式), developer(开发者模式) 和 production(生产模式)生产模式是最快的,它用于为上线网站提供动力。另一方面,为了调整和更改商店,您可能需要打开开发人员模式。

      要了解网站的模式,可以在Magento根文件夹中运行此SSH命令:

      php bin/magento deploy:mode:show

      要切换到生产模式,请运行:

      php bin/magento deploy:mode:set production

      HTML缩小可以缩小到高达原始页面大小的50%,因此您可以尝试一下。

      3.永远不要使用JS捆绑

      JS捆绑是Magento 2的一个特殊功能,它将JS文件分组在一起,以减少Web浏览器加载页面所需的HTTP请求数量。在HTTP1下可以使网站更快,但它对于HTTP2是没有用的。

      由于其他原因,JS捆绑也没用。发生的情况是,这个庞大的捆绑JavaScript文件 大小为5-12Mb,显着降低了商店的速度(尤其是在网络较慢的情况下)。

      所以去Stores > Configuration > Advanced > Developer > Javascript Settings并且设置启用JS捆绑为NO:

      JS捆绑在Magento中

      我建议使用HTTP / 2的强大功能,而不是JS捆绑。HTTP协议的新版本设计时考虑到了性能,并且可以真正加速任何站点,包括Magento。

      另一个解决方法是使用CDN(内容分发网络)。用它来加载静态文件比服务器加载的时间快了很多,而且它具有动态图像优化功能和各种缓存选项。

      4.合并和缩小CSS和JS文件

      Magento 2具有缩小CSS和JavaScript的内置功能。这对性能有好处,因为它可以减少页面负载。

      要设置缩小和合并,请转至后端菜单Stores > Configuration > Advanced > Developer > CSS and Javascript settings

      在Magento admin中缩小CSS JS

      请注意,JS / CSS minification仅适用于生产和默认运行模式。

      5.避免第三方CSS/JS框架

      我建议在构建Magento 2主题时避免使用任何外部前端库(除了那些最初与M2一起提供的库)。第三方框架可能使网站变慢。

      与Magento 2一起提供的jquery应该足以满足任何javascript需求。

      6.优化图像

      电子商务网站往往有很多图像。保持它们的优化和尽可能小的尺寸是非常重要的。

      我会在这里强调3种方式来照顾您的目录图片:

      1. CDN(内容分发网络) - 几乎所有这样的网站都具有某种图像优化功能。如果您的预算允许,您可以试一试。
      2. Google PageSpeed Module - 此服务器扩展(由Google开发)可以压缩图像并自动执行其他速度优化。您可能需要系统管理员帮助进行正确设置和配置。
      3. 各种在线工具 - 如果您没有那么多的图片,您可以逐个手动优化它们。有不少在线工具可以压缩图片。

      7.保持第三方扩展的数量最少

      根据我的经验,如果有一个缓慢的Magento网站,在大多数情况下,有很多自定义插件。市场上的一些第三方扩展可能会显著影响性能。

      自定义模块的问题在于,它们通常是在没有速度基准的情况下编写的。编码质量差是我建议将第三方扩展数量保持在最低限度的首要原因。

      如果你已经安装了一堆插件,那么该做一个审查了。逐个禁用它们并测量页面加载时间。如果扩展在第一个字节(TTFB)中超过100毫秒的时间,则可能需要联系其供应商并寻求补丁。

      如何找到安装的模块列表?在Magento根文件夹中运行这个SSH命令:

      php bin/magento module:status

      忽略以Magento_开头的模块- 这些是核心扩展。

      要禁用扩展,您可以简单地从app/code中删除它的文件夹并运行:

      php bin/magento setup:upgrade

      总结

      Magento 2自定义主题可能会很慢,但有一些方法可以使其更快速:

      • 注意第一个字节的时间,并尝试使用分析器来降低它。
      • 保持页面大小最小并始终压缩图像。
      • 检查主题模板并纠正不良的PHP代码块。
      • 缩小HTML,CSS,JS。
      • 不要使用JS捆绑 - 它有害无益。
      ]]>
      Fri, 08 Jun 2018 04:02:09 +0000
      <![CDATA[详细说明Magento2的所有产品类型]]> https://www.360magento.com/blog/magento-2-product-types/ 默认情况下,Magento 2中有6种产品类型:Simple, Configurable, Virtual, Downloadable, Grouped 和 Bundle Products它们与Magento 1中产品类型一样。如果您使用过Magento 1,我想您非常熟悉这些类型的产品。然而,如果你仍然好奇并想更多地了解它们,这篇博客会为您提供每种产品类型的详细说明。

      1.简单产品(Simple Products)

      这是Magento商店中使用最广泛的产品类型。简单产品是具有单个SKU的实物产品。简单产品可以单独销售,也可以作为可配置(Configurable)、分组(Virtual)或捆绑(Bundle)产品的一部分销售。

      实际上,大多数商店都使用简单产品,例如:书,包,手表......

      magento产品类型简单的产品

       

      2.可配置产品(Configurable Products)

      一个可配置产品似乎是一个单一产品,每个变体都有选项列表。但是,每个选项代表一个独立的简单产品,具有不同的SKU,这使得可以跟踪每个变体的库存。

      可配置产品的一个最好示例是T恤。购买一件T恤,顾客可以选择不同的颜色或不同的尺寸。

      magento产品类型可配置产品

       

      3.虚拟产品(Virtual Products)

      虚拟产品没有实体存在,通常用于诸如服务,保证和订阅等事情。这些类型的产品不需要运输,交付或下载。

      magento产品类型虚拟产品

       

      4.可下载的产品(Downloadable Products)

      一个电子下载产品包含一个或多个下载的文件。这些文件可以存储在您的服务器上,也可以从其他服务器提供的URL作为下载。

      示例:软件,视频,电子书,...

      magento 2产品类型可下载的产品

       

      5.分组产品(套)

      分组产品只是一组单一产品。您可以提供单个产品的变体,或将它们分组以供升级。产品可以单独购买,也可以分组购买。

      实际上,您可以使用此产品为想要一次购买多种产品的客户提供促销。或者您可以将其用于一组产品。例如:一套家具,一套行李如下:

      magento产品类型分组产品

       

      6.捆绑产品(Bundle Products)

      一个捆绑产品可以让客户从各种选项中“建立自己想要的”。该捆绑包可以是礼品篮,电脑或任何可以定制的东西。捆绑包中的每个物品都是独立的产品。

      magento 2产品类型捆绑产品

      根据具体的商品和服务,每个商店可以使用不同的Magento 2产品类型。如果您仍然对这些Magento 2产品类型感到困惑,请联系我们,我们将举出更多例子为您解答,并根据您的产品特性指定不同的产品类型。。

      ]]>
      Thu, 07 Jun 2018 09:03:12 +0000
      <![CDATA[如何保护Magento 2中的原始产品图像?]]> https://www.360magento.com/blog/protect-product-images/ 问题:

      开发人员启用了Magento 2的水印功能,但仍可从URL访问没有水印的原始产品图像。

      例如:

      缓存的带有水印的图片地址:

      /pub/media/catalog/product/cache/df484df48ez74849c15sd4f7780/f/f/dsf-8f48d4f.jpg

      没有水印的原始图片地址:

      /pub/media/catalog/product/f/f/dsf-8f48d4f.jpg

      因此,如果有人 从URL中删除/cache/df484df48ez74849c15sd4f7780/ 仍然可以访问无水印的原始照片来窃取图像。

      开发者如何保护他的原始产品图像?

      解决方案:

      这里的简单解决方案是修改和使用以下/var/media/catalog目录中.htaccess文件:

      Options +FollowSymLinks
      RewriteEngine on
      
      #The next coding line permits the original images to be accessed by admin end directly
      
      RewriteCond %{HTTP_REFERER} !^http://www.yourwebsite.com/.*$ [NC]
      
      #The next coding line permits the watermarked images to be accessed directly. It is according to the rule where the URL does not contain a cache.
      
      RewriteCond %{REQUEST_URI} !(/cache/) [NC]
      
      #It is the page where your store visitor will be redirected if they will attempt to access images directly.
      
      RewriteRule \.(gif|jpg)$ http://en.wikipedia.org/wiki/You_shall_not_steal [R,L]

      上述安全措施将帮助开发人员防止他的Magento产品图像被盗,下载和复制。

      我们向您展示了一种简单的方法来保护Magento 2中的原始图像文件。如果您在遵循该指示时遇到任何问题,请联系我们

      ]]>
      Wed, 06 Jun 2018 01:34:50 +0000
      <![CDATA[如何修复在Magento 2中重新索引时的死锁错误?]]> https://www.360magento.com/blog/error-reindexing-m2/ 问题:

      Magento版本:2.1.9 
      模式:Production
      索引模式:Update on save

      总产品:18k 
      总客户:54k 
      总订单:18k

      开发人员尝试重新建立索引后,会生成exception.log文件,其中包含此文件中的以下错误。同时,服务器被卡住,需要重新启动。然后,该网站才可以照常运行。

      “PDOException: SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction”

      那么,如何解决这个死锁错误以及手动重新编制索引的最佳方法?

      解决方案:

      有3个简单的步骤来处理这个Magento 2死锁错误:

        • 第1步:在本地打开数据库,然后运行SQL:

       

      DROP TABLE `catalog_category_product_index`;
      DROP TABLE `catalog_category_product_index_tmp`;
      
      
      CREATE TABLE `catalog_category_product_index` (
        `category_id` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Category ID',
        `product_id` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Product ID',
        `position` int(11) DEFAULT NULL COMMENT 'Position',
        `is_parent` smallint(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Is Parent',
        `store_id` smallint(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Store ID',
        `visibility` smallint(5) UNSIGNED NOT NULL COMMENT 'Visibility'
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Catalog Category Product Index';
      ALTER TABLE `catalog_category_product_index`
        ADD PRIMARY KEY (`category_id`,`product_id`,`store_id`),
        ADD KEY `CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY` (`product_id`,`store_id`,`category_id`,`visibility`),
        ADD KEY `CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION` (`store_id`,`category_id`,`visibility`,`is_parent`,`position`);
      CREATE TABLE `catalog_category_product_index_tmp` (
        `category_id` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Category ID',
        `product_id` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Product ID',
        `position` int(11) NOT NULL DEFAULT '0' COMMENT 'Position',
        `is_parent` smallint(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Is Parent',
        `store_id` smallint(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Store ID',
        `visibility` smallint(5) UNSIGNED NOT NULL COMMENT 'Visibility'
      ) ENGINE=MEMORY DEFAULT CHARSET=utf8 COMMENT='Catalog Category Product Indexer Temp Table';
      ALTER TABLE `catalog_category_product_index_tmp`
        ADD KEY `CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID` (`product_id`,`category_id`,`store_id`);

        • 第2步:尝试在本地重新索引

        • 步骤3:如果您可以在本地重新编制索引,然后再在服务器上重新编制索引

       

      我们向您展示了3个步骤来解决在Magento CE 2.1.9中重新索引时发生的死锁错误。如果您在按照说明进行操作时遇到任何问题,请联系我们

      ]]>
      Tue, 05 Jun 2018 01:33:02 +0000
      <![CDATA[2018年Magento电子商务网站20大免费网站速度测试工具(第2部分)]]> https://www.360magento.com/blog/website-speed-test-2/ 上一篇博客文章中,我们向您展示了Magento电子商务商店的前10款免费网站速度测试工具。今天,我们将继续推荐给您可以免费获得的剩余10个有用的测试工具。让我们开始吧!

      所有Magento电子商务网站都应该知道20个推荐的免费网站速度测试工具...

      11. Chrome DevTools

      google devtools

      这是开发人员最熟悉的免费网站速度测试工具之一,因为它很容易在本地环境中测试和调试。

      要启动DevTools,只需打开Chrome浏览器,然后按下组合键即可:

      • 对于Window / Linux:Ctrl + Shift + I
      • 对于Mac:Cmd + Opt + I

      之后,将会显示您的Magento电子商务网站的详细分析。以下是关于Chrome DevTools您可能想要了解的更多信息:

      • 通过使用Devetools,您将能够增强您的网络连接,禁用缓存,检测缓慢的第一个字节时间,获取页面渲染截图等。
      • 此外,您可以计算出确切的DOMContentLoaded时间,其总加载时间,或阻止资源以及如何处理它。Network -> Show Overview -> Ctrl+R/ Cmd+R -> refresh
      • 作为Google性能审核的强大自动化工具,Lighthouse已整合到Devtools中。因此,您将知道根据糟糕的审核来如何改进您的网站。

       

      12. MobiReady

      尽管MobiReady是一种新的测试工具,但它已被证明是最有效的免费网站速度测试工具之一,不仅适用于开发人员,设计人员,也适用于营销人员评估移动设备上的网站性能。

      MobiReady的特别之处在于它将根据W3C标准Google PageSpeed InsightsYahoo YSlow进行测试

      mobiready测试网站速度
      怎么运行的?

      • MobiReady在4种不同类型的设备(台式机,高端手机,中端手机和低端手机)上实施4项测试,以检查您的网站在同一时间的表现。
      • 它利用Chrome来下载网页的所有资源并检查尺寸。
      • 总体而言,MobiReady为我们提供了遵循行业准则的相对准确的分数。

      mobiready测试网站速度结果

      要根据MobiReady测试增强您的Magento商店,您必须点击每个测试来查看其详细信息以及解决方案。

       

      13. Varvy

      Varvy是电子商务网站最强大的一站式免费网站速度测试工具之一,可以检查您的速度,移动功能和搜索引擎优化(基于Google网站管理员指南)。在进行详细分析后,Varvy将为优化您的网站性能提供大量方便的提示和指导。

      更具体地说,测试结果包括摘要,页面资源图,CSS传递,Javascript使用率,速度问题,...
      varvy测试网站速度
      varvy工具测试网站速度

       

      14. Sucuri Load Time Tester

      Sucuri Load Time Tester工具提供了一种简单而快速的方式来评估您的网站在全球不同国家的表现。在检查每个区域的总时间(根据连接时间和第一字节的时间)后,Sucuri将分析并给您一个全球绩效等级(A到F)。

      更具体地说,这个测试有助于确定连接到您的网站以及您的网页完全加载需要多长时间。

      sucuri加载时间测试仪
      sucuri加载时间测试结果

      15.Think With Google - 移动端友好测试 

      Think With Google工具将帮助您了解您的网站是否适合移动设备,以及向您提供有用的增强建议。

      goodle移动友好测试

      此工具可让您将免费报告发送至您的电子邮件,或者只需点击即可将信息转发给您的网站管理员或开发人员。

      此外,Think With Google不仅可以分析您的Magento网站,还可以与同行业的其他网站进行比较。从那里,你会知道你如何来尝试克服你的竞争对手。

      goodle移动友好的测试结果

       

      16. Dareboost

      强烈推荐的另一个有用的免费网站速度测试工具是Dareboost。像Varvy一样,Dareboost是一款全面的工具,可以分析您的网站速度,性能监控和搜索引擎优化。

      dareboost免费工具来测试网站的性能

      这个测试工具将分析各种数据点(最多80个),例如:请求数量,可访问性,jQuery,缓存策略,浏览器渲染......

      与列表中的其他工具相比,Dareboost的安全报告非常特殊。它会显示您的网站是否缺少安全政策标头和SSL证书,或者您的网站是否遭受了点击劫持攻击等等。
      dareboost免费工具来测试网站的性能结果

      查看Dareboost报告,您可以快速发现您的Magento网站存在的问题并提出改进建议。

      此外,它还允许您每月进行测试并获得5个网站报告。

       

      17. WebPageTest

      由Google开发和支持的WebPageTest是一个了不起的开源工具,允许您使用浏览器(Chrome和Internet Explorer)在全球范围内的一个或多个地点实施免费速度测试。

      通过使用WebPageTest,您可以进行一些独特的测试,例如内容拦截,多步骤交易,连接速度或视频捕捉......几乎所有网站上的所有内容。

      更重要的是,您可以同时对3个网站进行测试,以便将您的网站与竞争对手的网站进行比较。

      webpagetest免费测试工具
      webpagetest免费测试工具结果

       

      18. Bitcatcha

      由于Bitcatcha,您的Magento网站将在8个地点(USx2,伦敦,新加坡,圣保罗,班加罗尔,悉尼和日本)进行测试。

      一旦测试完成,您将获得每个地区的具体时间,性能等级以及如何提高您网站性能的建议。

      此外,由于Bitcatcha提供的可用链接,您可以轻松分享测试结果。

       

      bitcatcha网站速度测试工具

      bitcatcha网站速度测试

       

      19. PerfTool

      PerfTool是测试你的Magento网站速度的另一个开源工具,托管在Github上。它提供了大量有关您的网站的有用信息,并以易于理解的方式显示结果。

      为了提供详细的报告,PefTool收集3个可信数据源,包括DevPerf,PageSpeed Insights和W3CJS。

      您的电子商务网站报告中有超过200个绩效指标。只需输入您的网站的网址,让PerfTool完成剩下的工作。

      perftool-网络性能速度测试

       

      20. Monitis

      最后一个你不应该忽视的网站速度测试工具是Monitis。这个工具很简单,但可以生成快速和可靠的结果。

      您的Magento网站将从3个不同的地点进行检查,即美国,欧洲和亚太地区。

      最后但并非最不重要的是,它允许您通过电子邮件,社交媒体或直接信息即时分享测试结果。

      monitis web速度测试工具

       

      总结

      如果您希望加速您的网站,首先,花时间找一个可靠的网站速度测试工具来评估您当前的表现,找出哪些需要改进以及如何去做。此外,市场上还有很多可用的免费网站速度测试工具,所以不需要你付费。希望你在这篇文章中提到的工具能找到一个合适的工具来测试你的网站。

      此外,在注意到您的问题后,如果您没有足够的知识和专业知识来改进网站,我们可以提供帮助。在Magento界拥有6年以上的经验,我们知道如何让任何Magento电子商务网站发挥最佳效果。通过发送您的请求到sales@360magento.com 或网站下方的联系方式以获得免费咨询,与我们联系

      ]]>
      Mon, 04 Jun 2018 01:48:00 +0000
      <![CDATA[2018年Magento电子商务网站20大免费网站速度测试工具(第1部分)]]> https://www.360magento.com/blog/website-speed-test/ 对于所有Magento电子商务网站,网站速度在客户体验和销售转化中起着至关重要的作用。我们在前面的博客中提到了很多简单的方法来提高您的网站速度。

      但是,在知道如何更好更快地创建网站之前,您应该测试当前的性能。

      在这个博客中,我们将向您提供20个免费网站速度测试工具的列表,您可以使用它们检查Magento电子商务网站的性能。让我们开始吧!

      所有Magento电子商务网站都应该知道20个推荐的免费网站速度测试工具...

      1. Google Pagespeed Insights

      8年前,谷歌宣布网站页面速度将成为搜索引擎优化排名的重要因素。同时,他们推出了Google PageSpeed Insights,一款功能强大的免费网站速度测试工具,可测量移动设备和桌面设备的网站性能,然后提出改进网站的具体方法。

      谷歌pagespeed的见解一旦您提交了需要测试的网站的URL,Google就会同时运行2个分析:

      • 第一个将检查上述内容的加载时间。换句话说,它衡量从用户请求新页面到浏览器呈现上述内容的那一刻为止所用的时间。
      • 第二个将测量提交网站的整体加载速度,从开始到页面完全呈现时。

      谷歌pagespeed洞察测试

      正如你所看到的,得分在0-100分的范围内。

      分数越高,您的网站的优化效果就越好。如果您的分数高于85,恭喜,您的网站表现非常好。
      谷歌pagespeed洞察测试

      与桌面报告相比,移动报告添加了一个名为“用户体验”的新类别,检查按钮和链接的大小,字体大小等。

      您可能知道,Google PageSpeed Insights一直在不断改进,因此随着新规则和更好的分析,分数将随着时间而改变。

      2. GTmetrix

      GTmetrix是另一种流行且易于使用的网站速度测试工具。
      一旦输入您的网站URL,此分析工具将立即扫描该网站,并在几分钟后提供您想要了解的网站性能的所有信息。

      gtmetrix网站速度测试
      在结果页面上,GTmetrix在顶部显示摘要,列出您的总体性能分数(PageSpeed&YSlow分数),满载时间,总页面大小和请求总数。

      尤其是,由于该工具在瀑布视图中显示了您的请求列表,因此您可以轻松识别您的站点中当前存在的问题。此外,该瀑布图允许下载以进行更深入的分析。

      此外,与谷歌PageSpeed Insights类似,GTmetrix测试还提出了一些可能的解决方案,以加快您的Magento电子商务网站。

      gtmetrix网站速度测试

      关于GTmextrix,您可能会感兴趣的还有更多:

      您可以创建一个免费帐户并保存多达20个速度测试,这有助于比较不同浏览器(Chrome / Firefox),位置,连接类型(有线/拨号)等的测试。

      3. Pingdom

      很多人认为Pingdom是近年来领先的免费网站速度测试工具。

      要进行测试,您必须输入URL并选择四个可用位置之一,包括美国(德克萨斯州和加利福尼亚州),澳大利亚和瑞典。

      检查完您的网站后,Pingdom将显示一个摘要,其中包含总体性能等级,总载入时间,页面大小,请求数量以及网站速度与其他网站的比较。

      与PageSpeed Insights一样,Pingdom会将您的Magento电子商务网站的性能评分为100。

      pingdom网站速度免费测试
      欲了解更多详情,您必须滚动到性能见解,这些见解表明每个元素的得分,并推荐具体的解决方案来增强您的网站性能。
      pingdom网站速度测试免费结果

      此外,值得注意的是,随着时间的推移,您可以跟踪您的网站性能,因为所有速度测试都将存储在Pingdom库中。

      4. Pagelocity

      Pagelocity也是当今最流行的免费网站速度测试工具之一。

      与前三种工具不同,Pagelocity不仅提供关于您的页面速度的见解,还提供关于您的页面SEO(源文件大小,文本大小,文本到HTML比率,URL长度)和代码的信息。

      每个测试方面的最高分数是100。

      另一个有趣的是,资源视图提供了关于哪些资产正在构成总页面权重以进行适当调整的信息。

      pagelocity网站性能测试
      pagelocity网站性能测试

      5. Dotcom工具

      下一个有用的免费网站速度测试工具,我们想为您的Magento电子商务网站建议是Dotcom-Tools。它能够同时在全球24个不同地点测试网站的性能。因此,获得最终结果需要相当长的时间。之后,它将显示平均加载时间,页面大小以及来自这些测试位置的错误数量。

      此外,您可以选择特定的浏览器进行测试,例如:Chrome,Firefox,Internet Explorer,和选择一个移动浏览器,例如:Android,iOS,Windows Phone,Blackberry等。

      经过快速检查后,您可以通过瀑布分解了解您的网站性能。

      dotcom-tools免费查看网站

      dotcom-tools免费查看网站结果

      6. YSlow

      与此列表中的其他网站速度测试工具不同,YSlow是一款开源工具,可帮助您根据23雅虎的高性能网站规则评估您的网站速度。

      此外,该工具还需要快速安装,作为浏览器的附件。

      yslow测试网站速度
      YSlow将在返回结果之前分三步进行操作:

      • 第1步:抓取DOM以查找您网站中的所有组件(例如:image,script)
      • 步骤2:收集有关这些组件的大小的信息(例如:gzip,过期头文件)YSlow需要
      • 第3步:为每条规则以及整体规则提供分数。

      在使用YSlow测试您的网站表现后,您将获得每个区域的特定等级(从A到F得分)。从这一点上,很容易知道哪些领域需要您关注并改进您的网站。

      yslow测试速度结果

      7.Load Impact

      Load Impact是另一款测试网站速度的免费工具。特别的是,该工具将同时从10个检查点生成负载,并且您甚至可以根据要求添加更多区域。

      负载影响测试网站速度

      处理完成后,Load Impact将显示一个信息图,显示当有更多用户访问您的Magento电子商务网站时,您的加载时间的波动。

      为了确保您的测试网站能够满足全球客户的需求,该工具将虚拟用户从多个地点发送到您的网站。

      更重要的是,Load Impact根据带宽使用量,请求数量和每秒请求数量显示了令人惊叹的统计数据。
      负载影响测试网站速度结果

      此外,Load Impact 为您提供5个免费网站性能测试和每月报告。

      8.Uptrends

      Uptrends是您的Magento电子商务网站的另一个便捷的免费网站速度测试,使您能够在全球35个地点进行测试 - 旨在确保您的网站能够快速加载来自世界各地的速度。

      就分析而言,Uptrends在瀑布或域中呈现丰富多彩的结果。因此,您可以诊断您网站的麻烦问题并快速处理。

      上升趋势免费网站测试工具

      上升趋势免费网站测试工具结果

      9.Geek Flare

      与以前的一些网站速度测试工具一样,Geek Flare可以让您从一系列不同地点的Magento电子商务网站的性能中立即查看,无论使用哪种设备。

      点击测试按钮后,您将获得第一个字节的时间(TTFB),满载时间,页面大小,请求数量,按类型的请求计数,响应代码和域等的结果。

      怪胎flare免费检查网站性能怪胎耀斑免费检查网站的性能结果

      10.Yellow Lab Tools

      与列表中的其他工具相比,Yellow Lab Tools似乎对某些人来说很陌生,但对于网站性能评估来说,它确实是一个不错的选择。

      更具体地说,该工具提供了大量有用的信息和一些独特的功能,例如在页面加载和其他代码验证问题期间查看JavaScript与DOM的交互。

      JavaScript时间轴将向您展示DOM在页面加载时如何精确交互。

      黄色实验室工具网站速度

      黄色实验室工具网站速度测试

      ]]>
      Sun, 03 Jun 2018 13:52:32 +0000
      <![CDATA[50种方法立即提升您的Magento网站性能]]> https://www.360magento.com/blog/improve-magento-website-performance/ Magento网站的性能对于每个电子商务企业的成功都至关重要。如果您的当前网站未进行优化,您的客户很有可能会在网站加载时离开。提高网站性能意味着您正在为访问者创造更好的购物体验,因此我们来执行以下方法:

      MAGENTO网站性能增强 - 快速配置

      1.启用cron和日志清理

      2.启用Use Flat Catalog Category和 Use Flat Calalog Product

      3.打开Magento的内置缓存

      4.启用合并Javascript文件 合并CSS文件以减少HTTP请求的数量

      5.卸载你不需要的所有扩展

      6.为类别和产品使用规范链接Meta标签

      7.产品URL不要使用类别路径

      8.删除类别URL后缀中的.html

      9.限制类别页面上的产品数量

      MAGENTO网站性能增强 - 应用程序级别修复

      推迟解析Javascript

      11.避免AlphaImageLoader过滤器

      12.避免URL重定向

      13.使用外部Javascript和CSS

      14.避免使用CSS表达式

      15.减少DOM元素的数量

      16.利用浏览器缓存

      17.删除重复的Javascript和CSS

      18.缩小Javascript和CSS

      19.启用gzip压缩组件

      20.将CSS放在文档头部的顶部

      21.使用CSS精灵组合图像

      22.优化图像

      23.优化样式和脚本的顺序

      24.避免不好的请求

      25.摆脱静态资源中的查询字符串

      26.避免使用CSS @import

      27.指定Vary:Accept-Encoding标头

      28.从一致的URL提供资源

      29.指定一个缓存验证器

      30.避免在元标记中设置字符

      31.使Ajax可缓存

      32.倾向于异步资源

      33.把Javascript放在底部

      34.使用内容分发网络(CDN)

      35.减少DNS查找

      36.避免HTTP 404 - 未找到错误

      37.启用gzip压缩

      38.使favicon小而且可缓存

      39.减小cookie的大小

      MAGENTO网站性能增强 - 配置级别修复

      40.优化cookie的大小

      41.禁用Magento日志

      42.清理Magento数据库日志

      43.为产品设置唯一的名称

      MAGENTO网站性能增强 - 服务器级别修复

      44.使用Varnish缓存

      45.使用Redis

      46.使用专用服务器

      47.使用最新的PHP版本

      48.使用高性能SSD驱动

      49.使用RAM 2GB以上,加上双核CPU

      50.使用单独的Web和数据库服务器

      正如你所看到的,为了保持和增强Magento网站的性能,我们必须做很多事情因此,如果您没有足够的时间或技术技能,最好找一个可靠的Magento服务商来提供帮助。凭借6年以上的Magento经验,360Magento电子商务解决方案可以帮助您在最短的时间内以合理的价格优化您的Magento网站性能。

      ]]>
      Mon, 28 May 2018 02:38:15 +0000
      <![CDATA[Adobe将收购Magento]]> https://www.360magento.com/blog/adobe-to-acquire-magento/ Adobe将收购magento

      据美国财经网站MarketWatch报道,Adobe(NASDAQ:ADBE)周一宣布,该公司将以16.8亿美元的价格收购电商公司Magento Commerce,从而为该公司旗下平台补充一个至关重要的组成部分。

      这项并购交易意味着,Adobe将与客户关系管理(CRM)软件服务提供商Salesforce.com(NSYE:CRM)等公司展开一场“肉搏战”。Adobe的数字体验执行副总裁布莱德·兰切尔(Brad Rencher)在周一召开的一次电话会议上说道,根据市场研究公司作出的估测,该交易代表着一个130亿美元左右的营收机会。

      在此之前,Magento就已经是Adobe的合作伙伴,该公司在2015年被收购,当时包括Permira、Sterling Partners、Longview Asset Management和Innotrac Corp.在内的一个投资者团体以9.25亿美元的价格从电商公司eBay(NASDAQ:EBAY)手中收购了Magento。同年11月份,Permira获得了Magento的全部股权。

      Magento的客户包括佳能和Rosetta Stone(NYSE:RST)等,另外还有与Adobe重叠的一些客户,如可口可乐(NYSE:KO)和雀巢等。据Permira称,Magento的总商品额(GMV)高达1500亿美元以上。

      根据交易协议,这项并购交易将在第三季度中完成。Adobe称,在交易完成之后,Magento首席执行官马克·拉维尔(Mark Lavelle)将继续领导该公司的大约700名员工,届时Magento将会成为Adobe旗下数字体验业务的一部分。

      ]]>
      Wed, 23 May 2018 07:55:13 +0000
      <![CDATA[如何在30天内将Magento 1迁移到Magento 2 ?]]> https://www.360magento.com/blog/migrate-magento-1-to-magento-2/ 毫无疑问,将Magento 1迁移到Magento 2有很多原因,特别是当Magento发布了最新的惊人版本--Magento 2.2.4时与Magento 1相比,Magento 2绝对能够带来更好的设计和性能。

      如果我们回到几年前,由于其不稳定性,很多人都不敢升级到Magento 2。Magento 2的第一个版本中有很多bug。但现在,当Magento似乎将所有努力都用于创新,改进和增强Magento 2功能时,情况就不同了。

      此外,您应该考虑尽快从Magento 1迁移到Magento 2,因为Magento可能会在不久的将来停止对Magento 1提供支持。

      除此之外,Magento 2迁移是一个复杂的过程,需要您的时间,金钱和努力。对于Magento开发者,他们可能知道它有多复杂; 因此这篇博客文章并非针对他们,而是Magento店主,他们将把Magento 1迁移到Magento 2.换言之,在今天发布的文章中,我们将向Magento商人展示如何在最佳的时间段内平稳,循序渐进地进行Magento迁移。

      Magento 2迁移前要知道的重要事项

      Magento1迁移到Magento2
      许多人认为将Magento 1迁移到Magento 2的过程更新到最新版本的Magento 1 相似

      但是,这是完全错误的

      更具体地说,Magento迁移意味着您将不得不从头开始构建Magento 2上的新网站,仅是从旧网站迁移数据。

      您无法继续使用当前的Magento 1主题,扩展和代码。我们将在下一部分详细介绍。现在,让我们深入Magento 2迁移过程!

      30天将MAGENTO 2移植到MAGENTO 1 ...

      根据我们的经验,平均完成Magento迁移过程需要4-5周(大约30个工作日)。但是,如果您的站点需要大量自定义功能和主题自定义以及大量数据迁移,则升级时间会更长。我们来看看迁移中会涉及什么:

      7天:查看旧网站并准备即将进行的迁移<准备>

      5天:主题迁移

      5天:数据迁移

      3天:扩展迁移

      5天:自定义代码

      2天:设置并配置新站点<配置>

      3天:测试,修复错误并上线!<测试>

      1.准备

      准备magento 2迁移

      在开始Magento迁移过程之前,请查看现有的Magento 1商店,并确定哪些是您真正需要的,并且需要迁移到新的网站。例如,尽管您的网站可能包含巨大的数据库资产,但您需要迁移的内容仅包括产品,类别,客户和订单。此外,就扩展而言,只需保留您认为必要的内容并删除冗余内容即可。

      之后,强烈建议您为Magento 1网站进行彻底备份,保留所有文件,文件夹和数据库以处理不良情况。

      此外,我们建议您为Magento 1和2商店使用相同的托管服务器(可选)。

      2.主题迁移

      magento 2主题迁移

      正如我们之前提到的,将主题和模板从Magento 1移至Magento 2新网站是不可能的。有几个解决方案:

      • 第一种解决方案:为Magento 2购买现成的主题以应用到您的新网站。在Magento市场,Themeforest,Magego等知名主题市场有数百种有吸引力的设计可供您进行选择......

      优点:您将为您的新网站设计有很多选择,节省您的主题设计和编码时间,并显著节省您的预算。它仅花费你从100-200美元就可以得到一个精心设计的Magento 2响应主题。

      缺点:其他Magento电子商务商店也可以购买主题,并且与您的店面外观相同。要处理此问题,您可以自定义主题以匹配您的品牌形象。主题定制的成本很大程度上取决于您想要定制的程度以及您与哪个Magento开发人员/设计师合作。

      • 第二种解决方案:查找并使用免费下载的Magento 2主题。Google搜索Magento 2 free theme可以找到很多结果。

      优点:此解决方案的明显优势是您无需花费一分钱就可以得到一个新颖的外观。

      缺点:与第一种解决方案相比,选择的Magento主题数量只有十分之一甚至更少。此外,这些免费主题和模板的质量不能保证。他们的大部分功能都非常有限。因此,您在应用到新网站之前应仔细检查。

      • 第三种解决方案:从头开始创建一个新的网站设计。对于这个选项,你可以找一个Magento开发商,或者只是一个有Magento经验的网站设计师根据你的需求进行设计。

      优点:获得满足您所有需求和要求的独特网站设计。

      缺点:您必须投入大量资金才能部署此解决方案。此外,完成PSD和前端编程设计可能需要1-2个月的时间。

      • 第四种解决方案:克隆你的Magento 1商店。如果你仍然想保持原有商店设计,你可以考虑克隆它,为你的Magento 2商店创造相同的外观界面。

      优点:保持所有购物者当前熟悉的Magento网站设计。

      缺点:网站克隆的时间取决于当前设计的复杂程度。但是,克隆一个网站,一般来说,也将花费大量的时间(平均至少1个月)。

      • 第5种解决方案:克隆您感兴趣的任何网站,并为您的新Magento 2网站创建类似的界面外观。

      优点:创建一个与您最喜欢的类似的新Magento 2网站设计,并为您的买家带来新鲜感。

      缺点:像第四种解决方案一样,这种方法会花费您的时间和成本。

      Magento主题迁移的最佳解决方案是什么?

      尽管为您解决Magento主题迁移问题引入了许多解决方案,但我们强烈推荐第一种解决方案。总的来说,利用现成的Magento 2主题将花费最少的时间(寻找适当的主题),金钱(拥有主题)和努力(用于安装和定制它)。我们的大部分中小型客户现在都选择此方案。

      此外,在新的Magento 2网站上部署主题的总时间(包括安装,配置和次要定制)平均为4-5天。

      3.数据迁移

      magento数据迁移Magento数据迁移是将您的所有数据(包括产品,类别,客户,订单,推荐信,评论......)传输到新的Magento 2站点的过程。诚然,这是Magento 2升级过程中最关键的阶段,要求您具备强大的知识和经验来进行迁移。否则,一个小错误可能会导致严重的数据丢失而无法恢复。

      要将您的数据库资产从Magento 1移至Magento 2,我们可以使用由Magento提供的便捷的Magento 2数据迁移工具该工具将使用map文件将数据转换到您的Magento 2商店。更具体地说,它将验证您的Magento 1和2数据库结构之间的一致性,跟踪数据传输进度,创建日志,然后运行数据验证测试。

      magento 2数据迁移工具
      要执行数据迁移,首先您必须通过composer安装数据迁移工具。请记住下载适用于您的Magento 2版本的正确版本的工具。例如,如果您在Magento 2.2.4上构建新网站,则必须安装具有相同版本(2.2.4)的数据迁移工具。其次,您需要将配置设置从M1迁移到M2,包括商店,网站,系统配置(运输,付款,税收)等。第三,是时候迁移数据库中的主要数据了。

      除此之外,根据您的产品,订单和客户的现有数量,需要3到5天才能将数据从Magento 1迁移到Magento 2。

      4.扩展迁移

      magento扩展迁移
      与主题一样,您不再可以在Magento 2商店中使用Magento 1扩展列表。你需要做的是找到提供相同功能Magento 2版本的模块和插件迁移到新站点。但是,并非所有Magento 1的扩展都有针对Magento 2开发的。在这种情况下,您可以联系多个Magento扩展提供商,要求他们为您的商店开发自定义模块。

      对于某些扩展,我们还需要从M2中迁移M1的数据,例如奖励积分和商店积分。

      平均而言,每个插件迁移需要3-4个小时,包括安装,配置和可能的冲突解决。

      因此,我们建议您选择并“迁移”到新网站的必要Magento扩展程序,以节省您的时间,金钱和精力。

      5.自定义代码(自定义)

      magento迁移中的自定义代码幸运的是,大多数Magento 1自定义代码与Magento 2兼容,因此您可以使用多个Magento代码迁移工具重写或迁移代码。我们经常使用Magento Code Migration Toolkit,使事情变得更简单。

      此外,值得注意的是,M1和M2的结构有几点不同,您需要仔细检查代码以确保它在新店中运行良好。

      6.配置

      从magento 1迁移到magento 2进程
      在主题,数据和扩展迁移之后,您已经完成了Magento 2迁移过程的80%。现在,您必须在新的Magento 2网站上完成配置,包括语言,货币,税收,电子邮件模板设置等。

      此外,搜索引擎优化在以后提高网站访问量方面起着重要作用。在Magento 2中,它允许您创建适合搜索引擎优化的URL,编辑元标题/描述/标签/关键字,添加图像替代,控制网站索引以及与Google服务(Analytics / Search Console / Adwords)集成。因此,不要忘记利用所有这些有价值的功能。

      7.测试

      magento 2迁移和升级
      Magento迁移过程的最后一个基本阶段是测试。您必须彻底检查并测试整个网站,确保所有内容都按照原站运行。以下是在Magento升级后测试商店时使用的建议清单:

      前端测试:

      店面外观

      • 主页
      • CMS页面
      • 页面内容
      • 横幅滑块
      • 页眉和页脚链接

      产品列表

      • 类别和子类别
      • 产品网格/列表模式
      • 分层导航菜单
      • 产品分类
      • 产品添加到购物车
      • 面包屑
      • 产品页面

      产品页面

      • 产品加入购物车/愿望清单/比较清单
      • 产品图片和视频
      • 产品数量
      • 产品价格
      • 产品描述
      • 产品评分和评论

      购物车

      • 产品添加到购物车
      • 数量变化
      • 产品删除
      • 折扣应用
      • 运费和税务计算
      • 小计和总价

      结帐页面

      • 来宾结帐
      • 帐单和运输
      • 运输和付款方式

      客户账户和信息

      • 客户登录和注册
      • 忘记密码
      • 客户帐户页面

      电子邮件

      • 注册确认
      • 重设密码
      • 订单确认
      • 联系我们提交
      • 通讯订阅

       

      后端测试:

      产品目录

      • 产品配置
      • 类别配置
      • 属性管理
      • 评论管理
      • Sitemap生成

      销售

      • 订单创建
      • 发票提交
      • 装运提交
      • 贷项凭证创建

      顾客

      • 用户管理
      • 客户群体创建

      促销

      • 目录价格规则
      • 购物车价格规则

       

      将MAGENTO 1迁移到MAGENTO 2的成本如何?

      magento 1到magento 2的迁移成本
      Magento 1到Magento 2的迁移成本可能很高,但它值得。根据您预期网站的复杂程度,价格可能会或高或低。例如,就Magento主题迁移而言,尤其是,您必须花费100-200美元购买现成的主题,或者高达1,000-2,000美元购买独特的设计或克隆旧网站。此外,您希望迁移的扩展程序越多,您必须支付的金额也越多。

      如果您不是自己将Magento 1迁移到Magento 2,而是请Magento服务商提供的Magento迁移服务,那么您的项目成本也将大大取决于Magento开发者的工时费。例如,美国以及沿海城市的Magento开发公司每个工作小时会收取75-150美元的费用,但您如果选择内的Magento公司只要一半甚至更少的费用(每工作小时20-50美元)。这个巨大的价格差距仅仅是由于地区劳动力成本的巨大差异。

      360Magento的Magento迁移服务

      凭借6年以上的Magento开发经验,我们能够以非常合理的价格提供流畅高质量的迁移过程。现在就联系我们,获取Magento 2迁移项目的免费快速报价和咨询!
      magento迁移

      总结

      从现在发生的情况来看,Magento 2是“现在”和“未来”,而Magento 1已经过时并且远远落后。如果您想为您的网站做到最好,请考虑立即实施Magento 2迁移。大多数竞争对手可能已经将他们的网站升级到Magento 2。

      ]]>
      Tue, 15 May 2018 11:03:16 +0000
      <![CDATA[选择专业Magento开发者/开发公司的10条准则]]> https://www.360magento.com/blog/find-magento-develpoer/ Magento于2008年3月31日发布,已成为全球领先的电子商务平台。 因此,越来越多的电子商务公司需要Magento开发人员来开发新网站或支持其现有网站。

      虽然有大量的Magento开发商和Magento开发人员可供选择,但是要找到在Magento开发方面拥有丰富的专业知识和经验,并且提供合理价格的合适合作伙伴还是很难的。

      magento开发公司

      假设你要为你的项目寻找Magento开发人员/开发公司,你会怎么做? 你会在在Google或百度上搜索并从几万个结果中选择一个可靠的结果吗?

      事实上,60-70%的公司会这样。 这并非不是一种好的方法,但如果你没有你想要的Magento程序员的选择特定标准,太多的选择最后可能会感到困惑。 因此,为了让事情变得简单,我们为您提供高效率寻找高质量Magento开发人员和开发商的10条基本准则。我们愉快的阅读下面的内容吧。

      1.明确你的需求和Magento开发人员必须需具备的能力。

      首先,你在寻找Magento开发人员和开发服务商之前一定要非常的清楚自己想要什么。关於这点,不妨来自问几个问题:

      你是需要这个Magento开发者来帮助你修复一个严重的bug或者处理一些持续存在的严重问题?

      您是否想要Magento开发人员开发自定义功能/从头开始构建网站/将网站迁移到Magento 2 /继续未完成的项目?

      你需要得到不断的支持,或者只是在紧急情况下才需要?

      你期望你的任务/项目多久完成?

      你更喜欢与Magento开发者自由职业者还是Magento开发商合作?

      您的预算是多少?

      聘请magento开发人员

      当您回答完完上述的问题,寻找合适的Magento开发人员这件事你已经做好了一半。

      例如,如果您需要获得帮助来解决网站中的几个主要但不是紧急的错误,您可以与一些Magento自由职业者开发人员合作。 相反,如果您的网站有一些需要尽快解决的关键问题,我们强烈建议您找Magento开发公司获取专业的Magento支持服务。

      另外,如果您需要得到持续不断的支持以确保您网站的高性能,建议您与知名的具有完善Magento解决方案的开发公司合作。

      此外,根据您的项目大小,您需要考虑是聘请专门的Magento开发人员还是整个Magento开发团队。 原因在于,从头开发新的Magento网站等大型项目工作量大,通常需要多位Magento程序员,您应该考虑雇用一个团队来保证您的项目质量并提高开发效率节约时间成本。

      决定谁能成你的合作对象的另一个因素是你的预算。 如,若钱对您来说不是大问题,您可以自由选择任何Magento开发人员或 Magento开发公司来合作。 但如果您的预算是中等偏低,您应该与内陆Magento开发公司合作(例如:武汉,成都,南京等)而非沿海城市的Magento电子商务公司。 通过这种方式,您可以在高质量完成工作的同时节省预算。

       

      2.检验Magento开发人员的专业知识和经验

      在明确定义您的期望之后,您现在可以开始在百度或其他搜索引擎上进行搜索,并参照我们的建议标准来寻找专业的Magento开发人员。

      总的来说,当你想聘请Magento程序员时,专业和经验似乎是最基本的考量因素。

      无论聘用Magento开发人员还是Magento开发公司,您都要选择至少拥有2年以上Magento经验的人一起完成你的项目。凭借一系列高级功能和大规模定制,Magento为其开发人员创造了真正的挑战,特别是初学者。

      magento开发商招聘

      那么,如何检查Magento开发者的经验? 这很简单。

      首先,直接询问他们。 他们从事Magento开发多久了,期间参与了多少个Magento开发项目,他们不得不面对的最严峻的Magento开发问题以及他们的解决方案。

      其次,请他们给您的项目提建议。 Magento专业开发公司将能够根据他们的经验为您提供合理的建议。 例如,当你想开发一个复杂的功能时,一个有经验的Magento程序员可以帮助你分析这个功能的哪些部分是Magento默认的,哪些部分需要定制,然后给你一个最佳的解决方案。

      此外,当选择Magento开发人员进行大型项目时,建议您了解他们使用版本控制工具的经验。 一般Magento专业开发公司在使用某些版本控制系统(如GIT,SVN)方面拥有丰富的经验。

       

      3.检查Magento开发人员的开发案例

      说的多不如做得好,因此不要只听他们说了什么,更要看他们之前做的案例!

      magento网站设计

      通过看他们以前的案例,检查他们开发的Magento网站,能评估他们是否能够满足您的要求。可以从前端设计和功能效果两方面入手,我们在同行网站中发现由他们大多数Magento开发项目都使用现成的主题和模板,因此您不需要过多地检查设计,而是专注于功能效果。 例如,您可以查看他们帮客户做了哪些额外功能,网站的速度,结账过程等。

      对于Magento网站开发公司,他们经常在自己的网站上展示他们的案例,以便您快速了解。

       

      4.找到真实的见证和反馈

      我们想要建议您的下一步是询问您想聘请的Magento开发人员/开发公司的以前客户的真实反馈。 有时候,一个好的案例不能告诉你整个故事。 例如,虽然最终的网站设计是完美的,但程序却无法按时交付。

      magento电子商务审查

       要获得以前客户的联系人,您可以直接询问Magento程序员或访问案例上的网站以获取信息。 之后,您可以通过电子邮件或致电这些客户咨询用后的体验从中获得参考。 以下是您可以询问过去客户的一些有效问题:

      他们聘请Magento开发人员/公司的项目/服务是什么?

      他们为什么选择这个开发商?

      项目管理如何安排的,效果如何?

      他们觉得这项服务最令人印象深刻/令人失望的是什么?

      开发人员是否按时按预算交付了您的项目? 是否会产生额外费用?

      他们有哪些地方可以改进?

      确保您聘用的Magento开发公司为其前客户提供高质量的工作,这对聘用者来说是至关重要的。

       

      5.询问后期开发支持和维护

      提供项目后的支持和维护至关重要,尤其是当您聘请Magento开发人员开发大型Magento电子商务网站时。 例如,在用户验收测试(UAT)之后,您无法找到开发站点中的所有错误,但这些错误发生在站点上线后。 在这种情况下,最好与最初的开发人员一起找出原因并解决问题,而不是找到另一位程序员。

      在360Magento,我们在客户网站上线后(Magento网站开发项目)提供3个月免费支持,以帮助他们避免及时解决任何可能的问题。 因此,我们始终能得到我们所有客户的100%满意。 经过3个月的免费支持,如果客户希望得到我们的进一步帮助,他们可以考虑使用我们的Magento年度支持服务。

       

      6.在寻找Magento开发者之前策划出项目的开发过程

      您可能知道,Magento项目中应用的开发流程和方法将决定它是否成功。 有很多东西可以使Magento开发过程成为可能,但这里有一些您需要关注的主要问题。

      首先,Magento开发公司必须为您提供一个详细的开发计划。 在这个计划中,它必须清楚地告诉你他们将在你的网站上做些什么,分成几个主要任务和多个子任务(次要任务)。 此外,每项任务必须有具体的完成时间。 例如,在360Magento,我们经常为每个项目制定详细的时间安排和时间表,包括一些特定的阶段,例如规划/准备,网站设计和网站开发(产品,客户帐户,管理员配置,发货, 付款,搜索引擎优化,数据集成,扩展实现,...),测试和UAT,以及启动。

      magento开发过程

      此外,大多数开发人员将在他们的开发服务器上部署您的网站,并且只有在您满意产品时才将网站移动到您的服务器。 问题是你必须问他们是否会让你访问他们的服务器。 否则,您很难跟踪和控制开发进度,并及时提出改进意见。

      您需要确保的另一件事是,您想合作的Magento开发公司是否有专门的测试人员在向您提供网站之前检查所有功能。 另一方面,要清楚在发现网站上的任何问题时如何报告。

       

      7.评估Magento开发人员的沟通技巧

      通常沟通问题是被许多人忽视的,但其实这很重要,尤其是在面对面会议几乎不可能的情况下外包Magento开发项目。 如果您要进行外地Magento开发,我们就必要具备能跟合作伙伴沟通的任何一种方式。 例如,你必须检查他们是否可以使用音频和视频会议,聊天工具如Skype,QQ或任何特殊的应用程序共享工具。

      此外,虽然英语现在变得越来越流行,但语言可能成为障碍。 因此,确保您选择的Magento开发人员有一定程度的英语流利度。

       

      8.在预算和Magento开发者期望酬劳之间取得平衡

      在美国,英国或澳大利亚,只需点击几下,您就可以轻松找到很多的Magento开发公司。 如果你想让这些公司来完成你的Magento网站项目,你就不得不做出巨大的投资。 他们中的大多数会否定预算低于10k的开发项目,并且最愿意接受大型项目(从4万美元到10万美元)。 因此,如果您有能力聘请当地公司,将Magento项目外包可能是一个理想的选择。

      此外,如果您合作一家专业的Magento开发公司,虽然您在工时费上花费较多,但您只需要花费一半甚至更低的成本来完成低价程序员的工作。

       

      9.确定开发人员专业程度

      一个常见的情况是,虽然该公司想建立一个Magento网站,但他们只是寻找一般的“网站设计和开发公司”。 因此,他们可以找到多家关于网站开发为名的公司,但是这些公司都没有专门从事Magento。

      你知道吗? 一家专注于Shopify的大型电子商务开发公司仍然可以帮助您建立一家Magento商店,但他们跟“真正的”Magento开发公司没法比的。

      因此,除了网站开发商的声誉外,您还应该了解他们的重点平台和开发技能。

      10.询问Magento认证(可选)

      现在,Magento为其开发人员和合作伙伴提供了多项认证,如Magento认证解决方案专家,Magento认证专业开发人员,Magento前端开发人员以及Magento认证开发人员和开发人员。

      如果Magento开发人员或Magento网页设计和开发公司可以展示他们的认证,那将是一个优势。 但是,我们将此步骤设置为可选,因为您不需要严重依赖它。 在某些情况下,如果你遇到一个认证的Magento开发者并且手头有很多认证,不要急于与他签署合同。 原因是这些认证可能通过作弊获得。

      此外,如果您的预算有限,并选择与Magento外包公司合作,即使他们在Magento拥有5-6年的经验,他们中的大多数也不能提供认证。 为什么? 对于那些程序员来说,加入Magento认证考试的费用和时间都很浪费。 此外,他们已经完成了大量令人惊叹的网站可以向您展示,这些将比这些证书更有价值。

       

      总结

      要寻找到一个可以满足您的所有需求并且接受您的预算的Magento开发人员/开发公司不是一件容易的事情。 但是,如果您遵循我们的建议,那么肯定会花费更少的精力为您的项目找到一个出色的合作者。

      凭借5年以上的经验,360Magento已经成为中国口碑最好的Magento开发公司品牌。 与一些代理机构不同,我们只专注于使用Magento构建的项目,并为客户提供最佳解决方案。 现在,我们提供广泛的Magento周边服务,从Magento网站开发Magento网站设计,Magento技术支持,Magento扩展开发Magento移动应用app开发Magento迁移到Magento优化。 现在就联系我们,为您的项目免费获得报价和咨询!

      ]]>
      Sun, 29 Apr 2018 13:39:48 +0000
      <![CDATA[Magento开发人员必掌握的SEO技术技巧]]> https://www.360magento.com/blog/seo-tips/ Technical SEO Tips

      在万维网初期,建立网站的想法和标准还处于起步阶段(甚至是萌芽状态),HTML使用的合法性以及在搜索引擎中寻找网站也超出了理解的范围。随着HTML开发和元素(即“标签”)的创建,网页结构变得更加标准化,搜索引擎处理交付高质量网站到桌面的方式也在不断发展。开发人员,设计师,内容创建者和搜索引擎都知道如何以及为什么应该构建结构的方式,最终开始成为真正的科学和艺术。

      曾几何时,搜索引擎只是寻找“关键字”来决定你的网页对搜索者是否重要; 然后考虑了内容和页面上有多少文字(因为如果有人正在为一个主题撰写5页的文章,那么他们的网页必须真的有关于该主题的大量信息并且非常有用,对吗? ),然后快速进入今天的谷歌化世界,我们有非常智能的搜索引擎,这些搜索引擎由非常复杂的人工智能算法提供支持,一切考虑从关键字到内容长度,以及所有这些关键字和内容是否与文章有关,以及网页内容的结构以及整个网站的结构。

      这一切都可以回溯到开发人员这个重要的位置,因为他们是那些真正建立起信息丰富而美丽的网站的人,这些网站将为您正在搜索精确主题提供引人注目和有用的网页。

      自Magento开发人员的八项SEO技术技巧

      1.页面结构

      一个网页有三个主要部分:头部,主体和页脚。头部(HTML元素<head>)包含指令其他元素,用于告诉加载页面(您的浏览器)的页面结构,构建页面所需的资源(调用CSS和JavaScript组件)以及在元数据元素<title>,<meta name =“keywords”>和<meta name =“description”>中找到的描述您(或网页抓取工具)正在查看的页面的基本信息。

      页面的主体(元素<body>)包含页面的主要内容。这是内容区,所有这些标题和响亮的段落信息都是为​​了您的阅读享受而制定的。本节的结构和重点也非常重要,因为有一种处理人和机器人阅读器(即搜索漫游器)内容的特定方法。这篇文章稍后会详细介绍。

      2.元数据

      正如其标签和属性所暗示的,这些部分提供了页面的主要标题以及简短描述(通常用于搜索引擎)以及帮助将搜索引擎定位到页面的所有关键字。这些部分可能是最容易创建的,也是最容易出错的搜索引擎优化。事实上,由于滥用关键字meta,现代搜索引擎常常忽略它,但将考虑一些,所以只要设置正确,它仍然有用。

      拥有一个正确的关键词仅仅意味着只提供与页面相关的关键词,而且这些信息应该保持在最低限度,因为页面的目标对象不应该超过几个字。另外,要记住,这是相对于页面的,而不是整个网站!

      标题和描述元应包含关键词为好,但就像关键词部分本身,他们应该简洁和集中。如果太短了,它们就不能提供有效信息。太长了,它们会分散注意力,容易失去焦点。这些元素看似简单,可能太简单了,对于页面的初始“快照”,它们是非常重要的。把它们看作是将被搜索引擎索引的“名片”。

      3. HTML标题

      这部分似乎困扰了许多网络开发人员和内容创作者的角色,因为这些标题的真实意图经常被误解。大多数曾经创建或改变网页的人很快就知道,在页面上放置文本时选择<h1>或<h2>或<h3>标签意味着改变字体的大小,以及粗体(或不粗体)的大小。这是一种简单易用的网页设计,因为当需要大胆突出的页面上放置任何内容时,您不必选择字体大小和粗体(取决于设计平台,实际使用的字体)。这种快速而肮脏的设计的缺点在于,您可能会在整个页面上放置不正确或多次的标题迭代,甚至没有意识到它,这对读者来说可能看起来很好,

      所以这里有个秘密:想想你的网页(和整体网站)的结构,比如一本书的内容部分。您需要一个干净整洁的标题和小标题列表,以准确,合理地组织您的所有信息。

      标题(即标题标签)的重要程度从1到6进行编号。您网页的主标题(您文章的“标题”)应位于<h1>元素内。页面上的后续标题应该用下一级重要性来表示:<h2>,<h3>,<h4>等等。除非声明一个全新的节,否则在页面上永远不应该有另一个<h1> 与之前的<h1>具有相同的重要性。由于大多数网页几乎不会做到这一点,它实际上不应该存在。

      “......但是如果我想在我的页面中间添加一个非常大而粗体的字体呢?”

      那么,说实话,你没有。为什么?因为搜索引擎也会将粗体文本视为重要的内容,因为您已尽力使其突出。这会引起某些文本突出显示的重要性内容的细微差别。不过,这里不要太疯狂,因为这也是一种被大量滥用的旧技术,就像汤一样,太多的好香料可能会破坏一锅好汤。

      这里给你一个学习者的图片:

      技术SEO技巧

      在上面的图片中,您可以看到页面中甚至有多个部分,其中导航菜单和侧栏可能存在于正文的上方或旁边,但是主体的<h1>标题是页面主要标题。小标题标出主标题下面的每个主要部分,等等。作为一个提示,页脚部分不一定需要标题标签,因为这些标签通常只是链接到其他页面,但是如果在这些标题下还有简短的描述(因为某些设计模板提供的框允许缩短内容描述),那么坚持格式是有帮助的。

      4.图像的“Alt”和“Title”属性

      图像上的这些属性至多被滥用(或使用不当),最坏的情况完全被忽视。这些对您的搜索引擎优化不仅有帮助,而且对于越来越重要的领域是强制性的

      “alt”和“title”属性可用于所有图像,旨在提供“爬虫”无法从图像本身收集到的额外信息(因为漫游器无法看见图像)。

      <img src=”images/happycat.jpg” alt=”A happy cat, drinking some milk from a dish.” title=”Happy cat drinking milk.” />

      此图像元素示例显示如何正确使用图像的“alt”和“title”属性。图像文件名本身不仅帮助搜索引擎找出图像可能涉及的内容以及它与它所在的页面是否相关,而且“alt”属性有助于提供图像的简明描述,而“标题”属性提供了更加直接和简洁的内容。这两个属性都可帮助残疾人士使用“web reader”查看网页,以便查找这些属性并将页面上的图像描述给最终用户,否则这些用户可能无法清楚地看到图像或难以辨别图像是什么。同样,添加这些属性不仅可以帮助网络爬虫确定您的页面及其提供有价值的信息,还表明你花时间去编辑更好页面可以被搜索引擎索引和完全消化,以及所有的最终用户可能会发现你的页面是一个有价值的信息来源,

      5.站点地图

      站点地图是为网页抓取工具和搜索引擎提供网站“地图”的文件。他们可以告诉搜索引擎您网站上的哪些网页是最重要的,因此首先要抓取什么,以及其他元数据,例如网页上次更新时间,以及何时需要重新索引。

      当启动一个没有大量外部链接指向的新网站时,包含网站地图就显得尤为重要,因为网络爬虫在单次访问中花费有限的时间来抓取网站。通过提供站点地图,网络爬虫将充分利用来自其中一个外部链接的每次访问,首先抓取优先页面并忽略自上次访问以来尚未更新的页面。

      6.网络分析

      网络开发人员为他们构建的任何网站设置网站分析,并让适当的个人访问分析仪表板很重要。检查用户在查找您的网站时搜索的关键词以及它们如何点击它们可以帮助为搜索引擎和用户剪裁内容。

      7. 404错误

      网站质量对于高搜索排名非常重要,并且当网站向网页抓取工具编制索引错误时质量受到很大影响。一个网站的404页面未找到错误越多,它就越糟糕。使用Google的Search Console或网站分析仪表板查找错误,并确保及时删除死链接。如果外部链接为您的网站产生大量流量,但是对于死链接或不正确格式的网址,请考虑设置重定向至其打算访问的网页。

      8.页面加载时间

      跳出率,因为网页加载时间越长,用户在仅查看一个网页后离开网站的几率就会大幅增加,。根据谷歌的说法,从一秒到两秒的加载时间增加了两秒,使跳出率增加了32%,而从一秒增加到五秒则增加了90%。Web开发人员可以通过优化图像文件大小和压缩CSS和JavaScript文件来减少页面大小。

      开发人员的专业知识对于正确的搜索引擎优化网站至关重要。如果您认为您的Magento网站需要技术审查,请联系我们以了解更多关于我们提供SEO服务的信息

      ]]>
      Wed, 11 Apr 2018 02:23:36 +0000
      <![CDATA[关于Magento 2 应用PWA的论述]]> https://www.360magento.com/blog/m2-pwa/ 什么是PWA?

      PWA全称是Progressive Web App,翻译过来即“渐进式Web应用程序”,我更愿意叫渐进式增强web app,是google在2015年提出,16年6月开始推广的项目。PWA的目的是使web应用通过渐进增强的方式来更接近原生app的体验及功能。

      PWA有哪些特点?

      1.添加到手机主屏

      用户首次用浏览器浏览网站,会提示添加应用到主屏幕,你的手机屏幕上就会出现一个应用图标,这就跟app一样,有app图标和标题,外形上无差别。并且无须在应用商店下载,也不用更新,通过后台可实时更新变更内容。通过图标启动可看设置启动画面。

      2.推送通知

      即使浏览器未打开Magento 2网站上的任何页面,通知也会发送给客户,就像其他app推送通知一样

      3.在离线模式下仍然可以访问

      用户在没有网络的情况下,只要是以前浏览过的页面在离线状态下仍可浏览

      4.速度秒开

      pwa会将已经浏览过的页面缓存到用户手机本地(当然这个是可以设置缓存的具体页面),这样就享受火箭般的速度。

      以上4点其实就是原生app所具备的有点,而pwa具备了web应用和原生app的有点,不仅有原生app应用的良好用户体验,还具有web应用的搜索引擎友好性。一句话,既能像app一样用又能在搜索引擎上排名。

      复制一下网络上的:

      大家都知道Native app体验确实很好,下载到手机上之后入口也方便。它也有一些缺点:

      • 开发成本高(ios和安卓)
      • 软件上线需要审核
      • 版本更新需要将新版本上传到不同的应用商店
      • 想使用一个app就必须去下载才能使用,即使是偶尔需要使用一下下

      而web网页开发成本低,网站更新时上传最新的资源到服务器即可,用手机带的浏览器打开就可以使用。但是出了体验上比Native app还是差一些,还有一些明显的缺点

      • 手机桌面入口不够便捷,想要进入一个页面必须要记住它的url或者加入书签
      • 没网络就没响应,不具备离线能力
      • 不像APP一样能进行消息推送

      复制粘贴结束。

      最后说明几点,

      1.PWA还是web应用程序,基于浏览器。

      2.以上说的pwa特点目前能够完全在安卓手机上使用,而ios目前不支持添加到主屏和消息推送功能。但我相信在强大的压力下,ios也不得不进行妥协。

      3.Magento与google合作,计划在magento2.2.4版本加入pwa,这是一个设置接口插件。

      如果想要网站页面能有更好的用户体验还是在于设计与编程。响应式流行了几年,但界面的友好性不如app,如果你想做一款如APP界面体验的移动端PWA网站,请联系我们

      ]]>
      Mon, 02 Apr 2018 11:06:42 +0000
      <![CDATA[为什么Magento仍然是2018年的电商巨头?]]> https://www.360magento.com/blog/why-m-2018/ 首先,我们要问个问题:这些著名的电子商务品牌有什么共同之处?

      1. Samsung
      2. Ford
      3. Olympus
      4. Nike
      5. Coca Cola
      6. Christian Louboutin
      7. Lenovo
      8. Warby Parker
      9. Rebecca Minkoff
      10. Nestle Nespresso
      11. Fox Connect
      12. Vizio

      magento品牌

      你有答案吗?

      是的,他们都在使用Magento - 现今最流行的电子商务平台!

      不仅这些著名品牌,有超过25万电子商务品牌,大小规模,选择Magento作为他们的电子商务网站平台。

      为什么?

      Magento无疑是易于应用的,因为它配备了大量专用于电子商务的有用默认功能。此外,还有一个大型的Magento社区,这意味着当您的网站出现问题时,您可以轻松获得支持。

      尽管越来越多的电子商务平台出现(例如:Shopify,BigCommerce,Volution,3Dcart,...),但预计Magento仍将在2018年取得领先。

      以下是Magento如此独特以及电子商务行业最受欢迎的一些原因:

      Magento专为电子商务而设计

      Magento向我们提供全面的电子商务解决方案,不仅为客户提供良好的体验,还为开发人员和商店管理员提供了绝佳的体验。在过去的几年中,从Magento 1到Magento 2,我们都看到了一个功能丰富的电子商务平台,预装了所有基础工具,用于构建完美的电子商务商店。

      magento电子商务

      Magento是一个开源的电子商务平台

      你可能知道,Magento是开源的,这意味着它是一个结合了PHP和其他开源工具的免费平台。因此,Magento已经比竞争对手有了巨大的优势。

      此外,由于开源,Magento具有很强的适应性,并且易于定制以满足各种项目需求。

      更重要的是,该平台可为商店带来强大的性能和最大的安全性。

      magento开源电子商务平台

      Magento是快速和可扩展的

      如果您希望网页加载速度很快,那么没有电子商务平台可以比Magento做得更好。

      由于高端缓存技术,您的Magento商店将显著加速。

      有些人认为Magento只适合大中型企业,但事实并非如此。该平台适用于所有中小型企业,因为它非常灵活,并且在业务变得巨大时能够与您的业务共同发展。您可能会对其性能,稳定性和可靠性感到惊讶。

      magento快速页面加载

      Magento默认响应式

      Magento整合了HTML5,使您的商店能够很好地展现在任何客户的设备上,从台式机,笔记本电脑,平板电脑到智能手机。

      magento反应

      大量的Magento扩展

      所有关注Magento的用户关键之一是巨大的Magento扩展和模块市场。很容易找到并安装Magento插件来增强商店功能。

      magento扩展

      允许多个商店

      尽管大多数电子商务平台只允许您每个帐户只有一家商店,但Magento可让您通过一个后端/管理面板进行设置管理多家商店。因此,您可以同时控制所有商店的库存,订单,帐单和客户信息。

      此外,由于每个商店可能有不同的主题,您可以为每个商店分配一个子域。

      magento多个商店

      易与第三方集成

      Magento允许无限集成第三方组件,因此有助于大幅缩短开发和部署时间。

      此外,由于Magento中的可扩展API,您可以无任何障碍地连接到任何应用程序或插件。无论是追踪工具,支付网关还是运输或分析工具,您需要做的只是找到扩展并将其安装到您的Magento商店中。

      Magento的-API的集成

      对主机没有限制

      与Shopify或Volusion平台不同,Magento可让您自由选择喜欢的托管服务。因此,您将能够选择符合您的要求和预算的最佳托管解决方案。此外,如果您想迁移现有商店,则无论何时何地都可以,都没有限制。

      magento托管

      Magento社区令人难以置信

      由于Magento是一个流行的开源电子商务平台,已经建立了一个巨大的Magento社区,包括开发人员,代理商,店主,设计师,商业顾问,解决方案提供商和全球最终用户。

      magento论坛

      结论

      正如你所看到的,Magento为我们提供了广泛的功能,以创建完美的电子商务商店。这个平台不仅在2018年,而且在未来几年仍将是无与伦比的电子商务巨头。

      但值得注意的是,它需要开发人员具有一定的专业开发知识才能实现有效的Magento网站。因此,您必须更加努力地选择可靠的Magento开发公司来与之合作。

      凭借在Magento电子商务方面6年以上的经验,360Magento能够帮助您建立出色的Magento商店现在就联系我们,为您的项目获取免费报价。

      ]]>
      Thu, 29 Mar 2018 02:58:28 +0000
      <![CDATA[Magento2开源版(社区版)和商业版(企业版)的区别比较]]> https://www.360magento.com/blog/ce-vs-ee/

      我们一直听到客户这样的问题:

      “社区版(CE)和企业版(EE)有什么区别?”

      “Magento2与1有什么关系?”

      “我需要哪一个?”

      一旦我们通过他们的第一组问题来谈论他们,接下来的问题就是:

      “使用CE和EE创建Magento2网站各自的成本是多少?”

      “'我为什么要选择付费版本而不是免费版本呢?”  

      “如果我在CE上使用扩展,可以在EE上使用吗?”

      如果不深入了解您的业务,很难在短时间内回答这些问题。每个商家都是独一无二的,每个商家都有一套独特的需求,但我们可以详细介绍CE和EE之间的一些关键区别,因此商家在与我们或其他开发人员进行深入通话之前,可以更好地了解从哪里开始。

      Magento 1 vs Magento 2

      我们详细介绍了M1与M2的区别,以及为什么M2如此强大并值得升级。阅读关于这里不过,下面是一张备忘单,比较了Magento 2 CE和EE上对Magento 1的主要优势

      新的Magento 2(包括Magento 2 CE和EE)功能优化
      功能 M2社区版(CE) M2企业版(EE)
      搜索引擎优化
      现场管理
      目录管理
      目录浏览
      产品浏览
      结帐,付款和运送
      订单管理
      客户账户
      客户服务
      国际支持
      分析和报告
      移动商务
      本机设备应用程序
      营销,促销和转换工具

      Magento 2的新扩展程序

      当Magento 2推出时,Magento也改变了商家访问扩展的方式。商家可以访问Magento Marketplace以访问数百个扩展。扩展分为以下几类:会计与金融,市场营销,内容与定制,客户支持,付款与安全,报告与分析,销售,运输与配送以及网站优化。  

      许多扩展是免费的,但有些可能需要花费数百甚至数千美金。最重要是要考虑质量,可靠性和可用性的扩展支持。市场的好处是,所有的扩展都通过扩展质量程序进行了审查和测试。

      Magento2社区企业版可以提供什么。

      站在商家的角度考虑,我们推荐Magento 2企业版而不是Magento 1企业版。在Magento 1中,商家购买EE的兴趣不大。社区没有足够的额外功能让企业值得投资。值得注意的是,我们看到CE上的许多商家利用扩展来获得EE的力量而没有价格标签。这对一些人有效,但管理和维护一个健康的网站可能会很棘手。那些M1扩展网站可能会造成一些昂贵且耗时问题。

      但是,Magento 2 Enterprise并非如此。Magento2企业版包含了最新的和许多令人兴奋的开箱即用功能 - 不需要复杂的扩展!

      Magento 2 EE功能与CE版本
      功能 M2社区版(CE) M2企业版(EE)
      客户细分,有针对性的促销和销售 没有
      基于动态规则的产品关系 没有
      持久购物 没有
      自动电子邮件营销提醒 没有
      私人销售 没有
      礼品登记 没有
      赠送选项 没有
      奖励积分 没有
      商店积分 没有
      多个愿望清单 没有
      由SKU添加到购物车 没有
      退货管理授权(RMA) 没有
      内容管理系统 没有
      计划导入/导出功能 没有
      备份和回滚 没有
      内容的分段,合并和回滚 没有
      客户属性管理 没有
      网站和商店级别的管理员权限角色 没有
      价格和促销权限 没有
      记录管理员操作 没有
      每个客户组的类别查看和购买权限(限制目录访问) 没有
      订单归档 没有
      Solr搜索 没有
      全页面缓存 没有
      优化索引 没有
      可配置的订单追踪小工具 没有
      支持备用媒体存储 - CDN和数据库 没有
      PA-DSS认证/支付桥梁 没有
      强大的数据加密,散列和密钥管理 没有
      除了上面详细介绍的M2 EE功能之外,商户还可以全天候获得技术支持。这包括专注于帮助您从Magento商店获得最佳效果的专门客户经理。

      Magento2企业版费用及价格如何计算?

      Community Edition是Magento的免费版本 - 使用该平台不需要额外费用。

      企业版是Magento的付费选项 - 总费用因商家收入而异。

      收入(美元) 授权费用(每年) (美元) 百分比
      0 – 100万 22K min  2.2%
      1百万 – 5百万 32K 3.2% – 0.64%
      5百万 – 1千万 49K 0.98% – 0.49%
      1千万 – 2.5万 75K 0.75% – 0.3%

      特别是EE,商店的商品销售总额(GMV)越高,年费就越高。考虑到这一点,大商人通常认为EE的好处值得投资。较小的商户通常首先利用免费的社区版,直到他们可以增加销售额,以证明企业的投资。

      但是,考虑到CE与EE之间的关系,重要的是还要计算投资扩展的成本。不仅要考虑扩展的总体成本,还要考虑安装,设置和配置所需的时间,其中包括确保所有扩展都能很好地协同工作。随着时间的推移,更新和维护扩展也要不断的花费。

      虽然从CE和一些扩展开始可能更经济,但重要的是要考虑长期的商业计划。如果在接下来的几年中,需要安装数十个扩展才能获得所需的完整功能,那么从一开始就投入EE可能是值得的。

      什么版本的Magento最适合你?

      M2 EE和CE的简要概述是为了在早期阶段帮助商家研究和规划。我们非常乐意与商家交谈,了解他们的未来个人需求和目标。特别是当他们正在考虑重大的M2升级或像企业一样的投资时。我们希望帮助确保商家做出他们感到有信心的决定,并且不会后悔。Magento是一个明智的商业投资,如果做得适当,可以带来极大的回报。

      联系我们  以获取更多关于Magento 2 CE和EE的信息,我们将安排时间回答您的所有问题。

      ]]>
      Tue, 20 Mar 2018 13:16:40 +0000
      <![CDATA[Magento2认证考试已准备就绪]]> https://www.360magento.com/blog/m2-cert-ready/ 期待已久,Magento2认证专业开发人员考试已经启动。自2016年我们开始第一个magento2项目时,我们就一直等待这个认证考试。所有的客户都希望自己的项目能与magento认证开发人员合作,它为他们提供了可持续性和高质量的感觉。2011年的时候我们公司参与首批Magento认证考试并斩获5位认证开发人员,在他们的带领下,公司声誉及项目质量得到了极大的提高。此外Magento2的认证考试启动,我们将依靠magento认证考试来简化我们的招聘过程。

      Magento 2认证专业开发人员考试是一种主要基于场景的考试,旨在验证在以下领域对Magento 2进行定制所需的技能和知识:UI修改,数据库更改,管理员修改,结帐流程定制,订单管理集成和定制,目录结构和功能的变化。这门考试适用于对Magento 2开发概念和经验(推荐1.5年)有深入理解的Magento 2开发人员,可以实现自定义和定制Magento 2。

      关于考试

      • 60多项选择项目
      • 90分钟完成考试
      • 基于Magento开源(2.2)和Magento Commerce(2.2),适用于那些使用过任何版本的Magento 2。

      Magento U已经分享了Magento 2认证专业开发考试学习指南

      对于前端开发人员来说,要通过Magento 2 Certified Frontend-Developer考试,你必须等到5月份。所以你有一些时间来提高你的技能来实现这个吸引人的徽章。

      如此纯粹的指导,购买考试券(260美金),找到一个考试中心,注册参加考试并为自己挑战;)

      PS:你最多可以重试4次这个考试。

      ]]>
      Mon, 19 Mar 2018 13:11:39 +0000
      <![CDATA[为什么要升级到Magento2?]]> https://www.360magento.com/blog/why-m2/ 1.Magento 1官方将支持到2018年12月。当Magento停止支持Magento 1的过程时,他们将停止发布重要的安全补丁,因此所有安全风险将成为您的责任

      2.维护和增强Magento 1商店的成本将在一段时间内增加

      3.2016年已停止为Magento 1平台开发新功能

      4.与Magento 1相比,Magento 2具有更好的安全性

      5.Magento 1基于旧版本的PHP(5.6或更低),而Magento 2支持PHP 7,充分发挥其性能优势。正确的配置和正确的基础架构设置将使Magento 2上的网上商店性能比Magento 1好得多

      6.Magento 2的结账速度快了38%,能够比Magento 1的订单多出117%的订单

      7.Magento 2内置了全页面缓存和Varnish 4 支持

      8.Magento2的后台管理界面人性化,它允许甚至不懂技术的用户处理Web商店管理

      9.通过Magento 2管理面板产品创建工作流程更简单

      10.主题响应式和移动设备支持是Magento 2的核心

      11.Magento 2具有广泛的响应和搜索引擎优化友好的主题和综合视频

      12.更方便用户使用Magento 2.结账步骤更少 -顾客完成结账的机会更多

      13.Magento 2支持更多支付选项和网关

      这一举措 - 顺利还是痛苦?

      magento官方发布了一个迁移工具,可以帮你平滑的迁移数据(商店设置,产品,客户,订单,促销规则......)

      但是,正如那里清楚地指出的那样,主题和代码自定义(包括第三方扩展)将不可转移,这意味着它们需要在Magento 2上重做。

      因此,需要在前端界面和功能开发方面进行额外投资。在我看来,这应该被视为一件好事,因为:

      1. 它可以给你一些新的想法,让你重新思考你的整个业务
      2. 你将能够摆脱一些遗留代码
      3. 您可以提高网站的整体可用性

      让我们面对现实 - 如果您的商店有50多个扩展程序(根据我们近期的一些经验,甚至比这还多),Magento 2可能成为一个救生员,因为它可以让您重新思考和希望以更好的方式重做。带给客户一个崭新的更好用户体验的商店。

      如果您需要任何帮助为您的业务计划下一步,请告诉我们。

      我应该什么时候升级到MAGENTO 2?

      这很大程度上取决于您当前的网站和当前的状况 - 底线是,如果您的网站运行良好(顺利运行,订单很多...),并且您使用的版本不是非常过时(任何在CE1.8 和EE1.13之前的版本会被认为相当过时),但并不急于求成,您可以(也应该)开始探索Magento 2,请求您的解决方案合作伙伴结合您自己的想法并开始制定一些基本计划。

      如果您使用的是旧版本的软件,甚至是较新的版本,但出现严重的性能问题,并且最重要的是您已经安装了多个第三方扩展程序,现在将是计划进行升级的好时机。

      如果您需要认真做一些事情来显著提高商店的性能,那么您绝对应该启动Magento 2升级计划。

      谁在使用Magento 2?

      ninewest.co.uk Shop.landroverusa.com Shop.jaguarusa.com shopworld.seat.de Shop.jazzercise.com Rogersandhollands.com Scufgaming.com Oliversweeney.com Sassandbide.com Pumpunderwear.com Stoneandstrand.com Danarebeccadesigns.com Eberjey.com Shop.dilmahusa.com H2oplus.com alcatelonetouch.us Thehundreds.com Shoei-helmets.com Kingsouq.com graze.com

      ]]>
      Thu, 15 Mar 2018 08:55:32 +0000
      <![CDATA[Magento2有哪些优势?magento1和magento2有哪些区别不同?]]> https://www.360magento.com/blog/m1-m2/ 2016年整个圈子都在讨论一个热门话题magento2,我们也完成了比较性能测试并总结了评测结果 - Magento 2与Magento 1相比的优缺点。老实说,在那一刻,我们对结果感到失望,因为所有得出的数字不支持最新版本。但现在,magento已升级到2.2.3,其表现结果是令我们满意的,我们强烈建议考虑迁移到Magento 2。

      性能提升

      页面加载时间减少超过50%。它对那些经常在你的商店浏览购买的顾客有很好的体验。人们对页面加载时间变得越来越敏感,因此Magento 2的性能改进可以让访问者留在网站上。 如果一个电子商务网站每天赚10万美元,1秒的页面延迟可能会让你每年损失250万美元的销售额。- Kissmetrics 此外,它使您的电子商务商店对搜索引擎更具吸引力。

      用户友好方式

      改进了Magento 2后端管理UX界面。如果您熟悉Magento 1.x管理,您将会对新的界面视图感到满意。这个新的管理面板具有用户友好的界面,使管理过程直观清晰和简单。 - 响应式和触摸友好的导航 - 简单的产品创建工作流程 - 拖放布局编辑 - 4倍的产品导入能力

      新购物者体验特性

      实现高度个性化的购物体验是Magento 2平台的主要目标之一。它采用新的响应式设计参考主题,客户购物车中的产品图像以及更多种类的付款方式成功实施。

      简化结账

      以最少的步骤和所需的信息优化结账流程,让您的客户购买更快更轻松。

      灵活的架构

      下一代架构为您的网上商店提供了前所未有的灵活性。因为它具有模块化的代码库,所以很容易定制您的电子商务系统。它节省了上线时间并优化了部署流程。 更快地连接,操作和扩展任何主题或扩展。更广泛和高效的API将关注这些。

      时髦技术

      1. PHP 7
      2. Varnish(全页面缓存可实现更快的开箱即用性能)
      3. Redis
      4. 现代JS堆栈
      5. RabbitMQ
      6. Solr
      7. PHPUnit
      8. Composer (用于管理依赖)

      框架改进

      主要代码重构,以摆脱系统中的所有混乱 - 主要数据网格增强 - 现在可以为Magento应用程序启用/禁用模块 - 兼容HHVM和PHP 7

      高质量扩展

      Magento将Magento Connect重新整合到只提供高质量扩展的新Magento Marketplace中,因为要成为这个新的magento模块商店的开发公司,所有第三方解决方案都必须通过5级质量检查。

      平台季度更新

      每3个月Magento 2发布社区版和企业版的新功能

      Magento2定制开发认准老品牌开发商360Magento

      ]]>
      Thu, 15 Mar 2018 04:03:29 +0000
      <![CDATA[Magento首席执行官说,“每一个企业战略都是数字战略”]]> https://www.360magento.com/blog/digital01/ 据电子商务平台Magento首席执行官Mark Lavelle称,如果有任何组织没有受到数字化转型的影响,那么很少有公司会这样做。他认为,数字化转型现在是每个人都面临的问题,组织采取的良好做法是遵循成功模式。

      正在发生的数字转型现正在影响每一个行业,”Lavelle上周在悉尼举行的澳大利亚Magento Live 2018活动中表示。

      “这是因为现在吸引和留住客户是数字行为。我们把时间花在银幕上,社交媒体上,你的品牌必须超越的各个地方。“

      Lavelle还指出节省成本和效率的重大收益,特别是对于B2B企业。最终,这意味着数字化转型已成为每个组织的一个问题,成功意味着适应性强,以客户为中心的业务。

      Lavelle表示,Magento电子商务平台每年处理大约1,550亿美元的商品总量,显示出数字化转型的广泛影响和需求。

      按照收入

      根据引用IDC研究的Lavell的说法,公司正在迎头赶上,他们认为全球2000强企业中超过半数认为其收入依赖于数字体验。

      Magento首席执行官Mark Lavelle

      “世界上大多数大的企业都认为这是他们收入的增长点。所以,[它]远离实验阶段[它]是非常真实的。每个企业都意识到,他们的企业战略实际上是一种数字战略,他们首先得从头开始。“

      Lavell说,数字化的焦点正在被买家的期望“推向顶峰”。消费者现在拥有前所未有的信息,包括价格和库存透明度。“他们希望作为品牌能够全天候365天与您进行互动。”

      Lavell还提到“亚马逊效应”,供应和交付链已经完善到“事情可以立即完成”的地步。根据Lavell的说法,尽管这在B2C交易中最容易看到,但它对于B2B买家来说日益重要。

      消费者期望值的提高意味着组织必须“不断前进”并愿意尝试。“你必须弄清楚你的客户下一步想要什么,他们将采用什么新的创新。因为他们将快速采用它们。“

      成功模式

      Magento产品的本质意味着Lavell亲眼目睹数字化转型。他说随着时间的推移,他注意到了某些模式和数字转换的真相。

      “一旦组织对这四件事情感到满意,那就是当我们看到真正的数字化转变发生时,”Lavell说。

      1.大胆品牌

      “你必须有一个能够切入的品牌,”Lavell解释道。虽然在数字时代之前这是真的,但是这个要求变得越来越重要,据Lavell说。

      “你走进一个组织,你可以判断整个品牌是否将转向数字化转型,或者这只是一个侧面项目。”

      2.首先拥抱数字

      Lavell说,真正的转型是文化,它意味着打破孤岛,必须从顶端来。Lavelle表示,这是一项重要的事业,为其中之一就是公司丛生存到快速发展。

      “你可能必须改变你组织的方式,以便进行完整的数字化转型。当我们看到公司接受它时,它很快就会成为一种竞争优势。“

      3.增加业务灵活性。

      “你不会购买某些技术或平台期望它保持相同的方式。这是一个错误。这就是我们10-15年前做事情的方式,“拉维尔说。

      根据lavelle的说法,当今的趋势意味着选择灵活和可扩展技术至关重要。在Magento,他们称之为“拥有玻璃” - 参考客户的互动主要在屏幕上出现。根据拉维尔的说法,灵活性意味着他们可以通过各种渠道满足客户的需求,包括那些尚不明显的渠道。

      4.通过独创性创新

      拉维尔说,最终的数字化转型事实是“人为因素”。拉维尔说,企业迫切需要创新和创造力。“我们发现,这些开放式的创新方法往往会使大企业通过这些类型的变革。”

      他说,虽然公司通常没有这种内部人力资源,但Magento开发商提供解决方案的社区平台是一个很好的选择。比如360Magento专注Magento开发长达10年,其技术实力和信誉值得信赖。

      ]]>
      Wed, 14 Mar 2018 02:54:21 +0000
      <![CDATA[发现最新的Magento Imagine 2018发言人]]> https://www.360magento.com/blog/imagine2018/

      发现最新的Imagine 2018发言人

       

      看看一些精彩的主题演讲和分组会议发言人以及品牌,在这个新的视频卷轴中分享他们在Imagine 2018上的成功故事。 

      Imagine 2018是Magento专家和创新者最大的聚会,将于4月23 - 25日在拉斯维加斯举行。此活动是与3000多名商业专家和创新者联系的绝佳机会。加入我们。立即注册

      ]]>
      Tue, 13 Mar 2018 02:49:24 +0000
      <![CDATA[论magento1和magento2的速度性能优化问题]]> https://www.360magento.com/blog/magento-speed-up/ magento从2007年发展至今,也经历了十余年的磨练,如今也迎来了magento的换代产品magento2,无论从安全性,稳定性还是速度,其实都已经做的很好了。但现如今还有客户说magento速度很慢,那这类客户肯定是道听途说,自己根本就还没有搭建一个magento网站,网上说magento慢的帖子那都是10年左右的老帖子了。

      当然了,无论是magento 1还是magento 2,它可扩展性,灵活性,系统安全性和可靠性方面处于领先地位,但是所有Magento的高级功能和特性都是以拥有大量文件和大型数据库为代价的,也正因此,从理论上来说要比其他平台速度相对慢点,微不足道的。也可以从以下方面做一些优化。

      一、服务器的选择

      迈向优化Magento性能的第一步应该是找到一个适合的好的Magento服务器,magento对服务器的要求一向很高,所以我建议选择独立云服务器,服务器内部优化配置自己掌控,当然这也需要专业的技术做支撑。如果有成本的限制,比如刚创业的小商家,可以找一家可靠的共享托管服务器,针对magento优化的共享服务器。我可以推荐一家专门针对magento优化的服务器托管商SiteGround。推荐选择GoGeek套餐。这样后期如果做的好可以升级独立云服务器,节省成本。

      二、数据库服务器

      大部分网站直接把网站程序服务器和数据库服务器共用,当然这在数据量小,请求量少的情况下还是可行的,一旦数据量和数据请求量上去了,那网站的速度是非常慢的。如果遇到这种情况,我的建议是直接上RDS,不懂的可以搜索RDS,可以称之为云数据库。前不久接手了一个二手项目,用的是magento2.1.5,我还记得3月份开发的一个2.1.5版本的项目,那个痛苦啊简直不敢想象,无论是线上还是本地刷新一个页面比蜗牛还慢,而接手的这个项目竟然秒开,原来一看配置是用了RDS,这就是花了钱的区别啊。当然现在的magento1.9和magento2.1.6以上版本都还是非常快的。

      三、CDN加速

      我们打开浏览器按"F12"选择"Network",然后运行网站,我们会看到加载这个网站的静态文件所需的时间(比如:图片,js,css),插一句,如果有的图片加载时间过长,可以用工具适当压缩图片。当然,无论你的网站有大型图片还是居多的css和js文件,都可以通过cdn来加载,这意味着你的图片和css,js文件将从另外一台服务器上加载,并且可以在加载页面时防止服务器上出现不必要的压力。从而提高加载速度。

      以上三点都是需要Money,当然这些Money花的是值得的,而且是物美价廉。下面我简单介绍下通过magento后台设置来进一步优化速度。

      1.进入到System > Configuration > Catalog > FrontEnd,在 ‘Use Flat Catalog Category’ 和 ‘Use Flat Catalog Product’.选择“Yes”。我解释下,magento数据库采用EAV模型,说简单点就是要想查询一个数据,得从好几个表里面联合查询才能得到你想要的数据,而上面设置后,那么我们的程序在加载分类和产品相关的数据时就直接单表查询,单表查询和多表查询哪个速度快就不用我说了吧。

      2.禁用日志记录, 进入到System -> Configuration -> Advanced -> Developer -> Log Settings 来禁用

      3.另一个重要的步骤是定期清理cron和日志。进入到System > Configuration > Advanced > System -> Log Cleaning,在这里你应该启用日志清理,并设置尽可能最小的时间。

      4. 合并css和js文件,进入到System > Configuration > Developer进行设置.合并意味着减少请求,从而提升速度。在此提醒,如果是经过二次开发的网站谨慎操作,合并之后可能会出现问题,我建议在具有丰富经验的magento开发人员的指导下进行。

      5.运行预编译,进入到 System > Tools > Compilation,运行预编译,这将提升网站加载速度高达50%以上。但因为一些用户操作不当导致网站无法访问,我之前写过一篇文章,解决magento开启Compilation预编译网站无法访问

      6.最后一步就是开启缓存,进入到System > Cache Management

      以上六点为magento 1的后台操作指导,magento2方法一样,只是路径不同,我就不再赘述。magento2更多的时候需要去运行命令,这就需要更专业的人士啦。magento2对技术的要求性还是很高的。另外magento 2如果切换到生产环境模式速度也是非常快的。在网站的根目录下再行如下命令:

      php bin/magento deploy:mode:set production


      最后补充一点,能花钱解决的就花钱解决,自己去折腾肯定是浪费时间的,最后还解决不好,时间就是金钱,找专业的人做专业的事才是最划算的

      ]]>
      Thu, 25 Jan 2018 10:42:21 +0000
      <![CDATA[Magento 2.2软件的更新版本现已推出]]> https://www.360magento.com/blog/magento22-updated/ Magento 2.2已经达到了另一个重要的里程碑,这要归功于几个小时的测试和您的大量投入。随着Magento 2.2发布的更新版本,几乎所有的主要问题已经解决,代码现在稳定,并准备好开始提交您的扩展到市场。我们也对您的反馈感兴趣,请继续提交您在未来几周内发现的任何问题。 

      接下来的步骤,我们鼓励您: 

      查看Magento 2.2发布信息。 Magento 2.2  快速入门网站  包括发行说明,文档,向后不兼容的更改列表,以及更多帮助您准备发布。 
      下载该软件的更新版本。 Magento开源(以前的社区版)软件可用于GitHub上的所有开发者 解决方案,技术和托管合作伙伴可以通过签署在线协议  并提供GitHub帐户信息来访问私人存储库中的Magento Commerce(以前的企业版)软件  查看我们以前的  论坛帖子  ,了解更多关于这个过程
      测试版本。 请继续测试此最新版本,并在2017年8月21日之前通过GitHub提交任何问题。在该日期之后提交的问题很可能会在GA发布后得到解决。请注意,技术支持不适用于预发布软件。如果在网站上线之前计划/完成对GA的升级,开发人员可能会根据预发布代码启动客户构建。
      测试并提交您的Marketplace扩展。 从今天开始,我们鼓励您提交已通过新版本测试的扩展程序。要在GA中及时列出您的扩展,我们建议您将更新限制在composer.json和module.xml文件中。这将允许您的扩展程序通过加快的审查过程。有关 该过程的更多信息,请参阅我们最新的关于更新Magento 2.2的扩展和主题的博客文章  

      再次感谢您的支持和反馈。请务必定期检查,因为我们将继续每周更新代码。 

      最好的问候,  
      Magento团队 ]]>
      Tue, 15 Aug 2017 14:39:58 +0000
      <![CDATA[Magento2定制布局示例]]> https://www.360magento.com/blog/magento2-layout-practice/ 本章内容

      本文将一步一步演示如何进行布局的定制任务。也就是说,将演示如何改变Magento页面头部中顾客账户链接的布局。

      移动顾客账户链接

      在Orange主题中,OrangeCo想要把头部链接转换成下拉菜单,Magento Luma主题中完成的方式是这样的:

      magento2 layout customization

      要实现该效果,需要将头部链接用一个容器包住并在列表前添加一个箭头。

      默认的头部链接看起来是这样的:

      magento2 layout customization

      需要变成这样:

      magento2 layout customization

      步骤1:定义块

      OrangeCo应用了Luma主题。使用《Magento2定位模板,布局和样式》中的方法。找到显示头部链接的块被定义在:

      <Magento_Customer_module_dir>/view/frontend/layout/default.xml:

      ...
      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <body>
              <referenceBlock name="top.links">
                  <block class="Magento\Customer\Block\Account\Link" name="my-account-link">
                      <arguments>
                          <argument name="label" xsi:type="string" translate="true">My Account</argument>
                      </arguments>
                  </block>
                  <block class="Magento\Customer\Block\Account\RegisterLink" name="register-link">
                      <arguments>
                          <argument name="label" xsi:type="string" translate="true">Register</argument>
                      </arguments>
                  </block>
                  <block class="Magento\Customer\Block\Account\AuthorizationLink" name="authorization-link" template="account/link/authorization.phtml"/>
              </referenceBlock>
          </body>
      </page>
      

      步骤2:定义模板

      与上一步定义布局的同样方法相同,OrangeCo定义用来重新排列链接的模板:

      <Magento_Customer_module_dir>/view/frontend/templates/account/customer.phtml

      <?php if($this->customerLoggedIn()): ?>
          <li class="customer welcome customer-welcome">
              <span class="customer name" data-mage-init='{"dropdown":{}}' data-toggle="dropdown">
                  <span><?php echo $this->getCustomerName(); ?></span>
                  <button type="button" class="action switch"><span><?php echo __('Change')?></span></button>
              </span>
              <?php if($this->getChildHtml()):?>
              <div class="customer menu customer-menu" data-target="dropdown">
                  <?php echo $this->getChildHtml();?>
              </div>
              <?php endif; ?>
          </li>
      <?php endif; ?>
      

      步骤3:扩展base布局来增加一个块

      OrangeCo需要在容器header.panel中新建一个名为header.links的块用来移动链接。由于链接可以在不同模型中被添加,最好是在Magento_Theme模型的页面配置default.xml中添加这个块。

      所以下面的扩展布局被添加在Orange主题中:

      app/design/frontend/OrangeCo/orange/Magento_Theme/layout/default.xml

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <body>
              <referenceContainer name="header.panel">
                  <block class="Magento\Framework\View\Element\Html\Links" name="header.links">
                      <arguments>
                          <argument name="css_class" xsi:type="string">header links</argument>
                      </arguments>
                  </block>
              </referenceContainer>
          </body>
      </page>
      

      步骤4:移动链接

      要移动链接到header.links块,OrangeCo添加一个扩展布局:

      app/design/frontend/OrangeCo/orange/Magento_Customer/layout/default.xml

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
              <body>
                  <referenceBlock name="header.links">
                      <block class="Magento\Customer\Block\Account\Customer" name="customer" template="account/customer.phtml" before="-"/>
                      <block class="Magento\Customer\Block\Account\AuthorizationLink" name="authorization-link-login" template="account/link/authorization.phtml"/>
                  </referenceBlock>
                  <move element="register-link" destination="header.links"/>
                  <move element="top.links" destination="customer"/>
                  <move element="authorization-link" destination="top.links" after="-"/>
              </body>
          </page>
      

      现在,顾客链接看起来如下:

      magento2 layout customization

      最后是添加样式:

      magento2 layout customization

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 27 Feb 2016 15:20:16 +0000
      <![CDATA[Magento2通用布局定制任务]]> https://www.360magento.com/blog/magento2-layout-tasks/ 本章内容

      这篇文章描述了下面这些典型布局定制任务:

      提示:为保证你定制内容的稳定性和安全性,避免在升级中被删除。请不要改变Magento的模型和主题布局。要定制布局可以在你的自定义主题中扩展和重写主题文件。

      设置页面布局

      特定页面的布局在页面配置文件中被定义,在根<page>结点的layout属性中。

      例如:将Advanced Search页面的布局由一列布局改为带左侧栏的两列布局:app/design/frontend/<Vendor>/<theme>/Magento_CatalogSearch/layout/catalogsearch_advanced_index.xml

      <page layout="2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
      ...
      </page>
      

      在<head>里加载静态资源(JavaScript, CSS, fonts)

      JavaScript, CSS和其它静态资产在页面配置文件的<head>区域被添加,默认地<head>app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml中被定义。建议在你自定义的主题中扩展该文件来加载JavaScript, CSS和其它静态资产。下面的文件包含了一些你必须添加的文件的示例:

      <theme_dir>/Magento_Theme/layout/default_head_blocks.xml

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <head>
              <!-- Add local resources -->
          	<css src="css/my-styles.css"/>
          
              <!-- The following two ways to add local JavaScript files are equal -->
              <script src="Magento_Catalog::js/sample1.js"/>
              <link src="js/sample.js"/>
      		
          	<!-- Add external resources -->
      	    <css src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css" src_type="url" />
              <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js" src_type="url" />
              <link src="http://fonts.googleapis.com/css?family=Montserrat" src_type="url" /> 
          </head>
      </page>
      

      要添加外部资源时,必须要指明src_type="url"参数。

      你可以使用<link src="js/sample.js"/>或<script src="js/sample.js"/>指令来添加本地存储的JavaScript文件到你的主题。

      指定资源的路径必须是以下中的一个:

      • <theme_dir>/web
      • <theme_dir>/<Namespace>_<Module>/web

      添加条件注释

      条件注释意味着针对Internet Explorer给出特殊的指令。你可以给特定版本的Internet Explorer添加CSS文件。以下是一个示例:

      <head>
              <css src="css/ie-9.css" ie_condition="IE 9" />
          </head>
      </page>
      

      这样就能在生成的HTML中增加一个IE条件注释,如下:

      <!--[if IE 9]>
      <link rel="stylesheet" type="text/css" media="all" href="<your_store_web_address>/pub/static/frontend/OrangeCo/orange/en_US/css/ie-9.css" />
      <![endif]-->
      

      上面例子中的orange是被OrangeCo创建的自定义主题。

      移除<head>中的静态资源(JavaScript, CSS, fonts)

      要移除页面<head>中的静态资源,按照下面的扩展文件做些类似的修改即可:

      app/design/frontend/<Vendor>/<theme>/Magento_Theme/layout/default_head_blocks.xml

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
         <head>
              <!-- Remove local resources -->
              <remove src="css/styles-m.css" />
              <remove src="my-js.js"/>
              <remove src="Magento_Catalog::js/compare.js" />
      								
      	<!-- Remove external resources -->
              <remove src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css"/>
              <remove src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"/>
              <remove src="http://fonts.googleapis.com/css?family=Montserrat" /> 
         </head>
      

      注意,如果在初始文件中静态块带有模型路径(例如:Magento_Catalog::js/sample.js),那么在移除时也应指明模型路径。

      创建一个容器

      使用下面的例子来创建(声明)一个容器

      <container name="some.container" as="someContainer" label="Some Container" htmlTag="div" htmlClass="some-container" />

      引用一个容器

      要更新一个容器,使用<referenceContainer>指令。

      示例:添加链接到页面头部面板

      <referenceContainer name="header.panel">
              <block class="Magento\Framework\View\Element\Html\Links" name="header.links">
                  <arguments>
                      <argument name="css_class" xsi:type="string">header links
                  </arguments>
              </block>
      </referenceContainer>
      

      创建一个块

      块的创建(声明)使用<block>指令。

      示例:增加一个产品SKU信息的块

      <block class="Magento\Catalog\Block\Product\View\Description" name="product.info.sku" template="product/view/attribute.phtml" after="product.info.type">
          <arguments>
              <argument name="at_call" xsi:type="string">getSku</argument>
              <argument name="at_code" xsi:type="string">sku</argument>
              <argument name="css_class" xsi:type="string">sku</argument>
          </arguments>
      </block>
      

      引用一个块

      要更新一个块,使用<referenceBlock>指令。

      示例:向logo块传送图片

      <referenceBlock name="logo">
              <arguments>
                  <argument name="logo_file" xsi:type="string">images/logo.png</argument>
              </arguments>
      </referenceBlock>
      

      使用块来设置模板

      要设置模板的块,使用<argument>指令来传递。

      示例:改变page模板的title块

      <referenceBlock name="page.main.title">
              <arguments>
                  <argument name="template" xsi:type="string">Namespace_Module::title_new.phtml</argument>
              </arguments>
       </referenceBlock>
      

      模型的路径被指明关系到模型的view/<area>/templates/目录。<area>对应布局文件被使用的地方。

      修改块参数

      要修改块参数,使用<referenceBlock>指令

      示例:改变已存在块中的参数并添加一个新参数。

      初始块声明:

      ...
      <block class="Namespace_Module_Block_Type" name="block.example">
          <arguments>
              <argument name="label" xsi:type="string">Block Label</argument>
          </arguments>
      </block>
      ...
      

      扩展布局:

      ...
      <referenceBlock name="block.example">
          <arguments>
              <!-- Modified block argument -->
              <argument name="label" xsi:type="string">New Block Label</argument>
              <!- Newly added block argument -->
              <argument name="custom_label" xsi:type="string">Custom Block Label</argument>
          </arguments>
      </referenceBlock> 
      ...
      

      使用块对象方法来设置块性能

      有两种方式访问块对象方法:

      • <block><referenceBlock>使用<argument>指令
      • 使用<action>指令。不推荐使用该方法,不过可以用来调用未被重构,不能用<argument>的方法。

      示例1:使用<argument>为产品页面设置CSS类并添加一个属性

      扩展布局:

      <referenceBlock name="page.main.title">
      		<arguments>
      		    <argument name="css_class" xsi:type="string">product</argument>
      		    <argument name="add_base_attribute" xsi:type="string">itemprop="name"</argument>
      		</arguments>
      	</referenceBlock>
      

      示例2:使用<action>设置页面标题

      扩展布局:

      ...
      	<referenceBlock name="page.main.title">
      	    <action method="setPageTitle">
      	        <argument translate="true" name="title" xsi:type="string">Catalog Advanced Search</argument>
      	    </action>
      	</referenceBlock>
      	...
      

      元素重新排序

      在布局文件中你可以改变页面中元素的顺序,使用下面的方法即可实现:

      • <move>指令:允许改变元素的顺序和父亲。
      • <block>beforeafter属性:允许改变有同一父亲的元素的顺序。

      <move>使用示例:将产品页面中的stock availability和SKU块放在产品价格旁边。

      在Magento Blank主题中这些元素的位置如下:

      magento2 layout customization before

      让我们将产品库存和SKU块放到产品价格块的后面,将review块从product-info-price容器中移出。要实现这些,在app/design/frontend/OrangeCo/orange/Magento_Catalog/layout/目录下添加catalog_product_view.xml

      <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <body>
              <move element="product.info.stock.sku" destination="product.info.price" after="product.price.final"/>
              <move element="product.info.review" destination="product.info.main" before="product.info.price"/>
          </body>
      </page>
      

      这将使得产品页面看起来像这样:

      magento2 layout customization after

      移除元素

      使用<referenceBlock><referenceContainer>remove属性可移除元素。

      示例:移除店铺页面中的Compare Products侧边栏

      这个块在app/code/Magento/Catalog/view/frontend/layout/default.xml中被声明:

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <body>
      ...
              <referenceContainer name="sidebar.additional">
                  <block class="Magento\Catalog\Block\Product\Compare\Sidebar" name="catalog.compare.sidebar" template="product/compare/sidebar.phtml"/>
              </referenceContainer>
      ...
          </body>
      </page>
      

      要移除这个块,你需要在你的主题中扩展default.xml

      <theme_dir>/Magento_Catalog/layout/default.xml

      在这个文件中,引用已被添加了remove属性的元素:

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <body>
      ...
              <referenceBlock name="catalog.compare.sidebar" remove="true" />
      ...
          </body>
      </page>
      

      替换元素

      要替换元素,你可以移除它然后添加一个新的。

      相关文章:

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 25 Feb 2016 08:16:12 +0000
      <![CDATA[如何更新Magento插件]]> https://www.360magento.com/blog/magento-update-modules/ 要确认Magento插件的更新,首先你需要登录到后台。然后进入System -> Magento Connect -> Magento Connect Manager。在Extensions标签中点击Check for Upgrades

      magento update modules

      Magento连接管理器会自动连接到服务器并检查可用的升级。如果你的插件中有已发布的升级版,它们的背景色会被标记为黄色,你可以将升级应用到你的插件。注意!在升级前对你的Magento网上商店进行备份是十分重要的。在Action的下拉列表里你可以选择想要升级到的版本。然后点击Commit Changes进行升级。

      magento after update modules

      你所选择的升级包将被自动下载并应用。

      插件升级完成后你可以通过Refresh按钮来刷新页面。然后检测插件的状态,你会发现升级后的插件的黄色背景色消失了。Installed列中也会变为你刚才所安装的版本。

      现在你可以点击Return to Admin,检查你的插件是否有新的可用配置。当然,也要确认你的网上商店工作正常,没有错误。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 19 Feb 2016 13:56:25 +0000
      <![CDATA[Magento2布局的覆盖]]> https://www.360magento.com/blog/magento2-layout-override/ 本章内容

      并不是所有的自定义布局都能通过扩展现有布局来实现。如果自定义的量很大时,可以覆盖所需的布局文件。这就意味着你在主题中新建的布局文件将被用来代替默认的主题布局文件。

      在这篇文章中,页面布局,页面配置和通用布局被称为布局文件,它们的覆盖是一样的。

      这类覆盖了默认或父主题的布局文件被称为覆盖布局文件。

      关于自定义覆盖布局的例子

      • 抑制方法调用(如果块里有取消原始调用的方法,覆盖就没有必要了。这种情况下,你可以通过在取消方法调用的位置添加布局文件来自定义布局。)
      • 修改方法参数
      • 使用remove属性取消块/容器的输出
      • 为块和容器设置XML属性
      • 移除块参数
      • 修改并抑制句柄包容
      • 移除所有句柄指令,通过声明一个空句柄覆盖布局文件

      如何覆盖一个布局

      覆盖base布局

      在如下位置放置一个同名的布局文件:

      <theme_dir>
        |__/<Namespace_Module>
          |__/layout
            |__/override
               |__/base
                 |--<layout1>.xml
                 |--<layout2>.xml
      

      这些文件覆盖如下布局:

      • <module_dir>/view/frontend/layout/<layout1>.xml
      • <module_dir>/view/frontend/layout/<layout2>.xml

      覆盖主题布局

      在如下位置放置一个同名的布局文件:

      <theme_dir>
        |__/<Namespace_Module>
          |__/layout
            |__/override
               |__/theme
                  |__/<Parent_Vendor>
                     |__/<parent_theme>
                        |--<layout1>.xml
                        |--<layout2>.xml
      

      这些文件覆盖如下布局:

      • <parent_theme_dir>/<Namespace>_<Module>/layout/<layout1>.xml
      • <parent_theme_dir>/<Namespace>_<Module>/layout/<layout1>.xml

      注意:要覆盖页面布局文件时将文件名'layout'替换为'page_layout'

      自定义错误

      虽然布局覆盖机制提供了极大的定制灵活性,它也可以进行逻辑相关的改变。我们强烈建议你不要做以下修改:

      • 更改块名或别名。块的名字不应该被修改,块的别名也应该与父元素中的保持一致。
      • 更改句柄继承。例如,你不应该修改页面类型的父句柄。

      相关文章

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 16 Feb 2016 14:09:47 +0000
      <![CDATA[如何安装Magento模型/插件]]> https://www.360magento.com/blog/magento_connect/ Magento具有内置的为线上店铺安装附加模型的功能。基本上,你所需要的就是插件的key以及点击几下。在这篇教程中,我们将详细解释如何通过Magento Connet为Magento安装附加的模型/插件。另外,我们也将说明如何升级已有的模型/插件。首先,你需要进入Magento的管理员区域。然后进入 System -> Magento Connect -> Magento Connect Manager。

      magento connet

      Magento Connect Manager页面打开后你将被要求再次提供管理凭据。

      magento connet admin

      登录后你将看到两个区域:ExtensionsSettings。建议首先在Settings区域验证被选择的设置。

      magento connet setting

      Setting区域,有几个选项你可以按需配置。当然,前提是你知道你正在做什么。保持默认值是安全的。

      magento connet setting state

      Preferred State选项控制你安装的插件状态。有三个状态:稳定,测试和阿尔法。针对在线网站推荐选择稳定版。设置为测试/阿尔法能让你检查插件是否为最新版本,但是一般不推荐测试版插件,尤其是阿尔法状态的插件可能有bug并可能破坏你线上网店的功能。在插件下载和升级前做备份是非常重要的。这样的话,在下载安装插件后发生冲突的情况下,你可以运行备份进行恢复。做好备份后你就可以进入Magento Connect Manager-> Extensions标签,点击Magento Connect链接。

      这将为Magento Connect打开一个新的窗口并让你浏览可用的插件。这里有搜索功能,而且模型分为几类。

      magento available extensions

      这里有各种插件,有些是免费的。不论哪种情况都需要注册来获取插件key。指令是根据特定的插件。当你选择一个插件,点击Install Now按钮并选择相匹配的Magento Connect版本(Magento1.5以上选择版本2.0,其它保持1.0)。阅读插件许可协议,勾选"I agree to the extension license agreement"。最后点击Get Extension Key按钮。

      magento extensions version

      你将获取插件的key。

      magento extensions key

      这就是你需要复制并粘贴到你Magento Connect区域的key。然后点击Install按钮。

      magento extensions install

      新的插件会自动下载和安装。如果安装过程出现问题,将会显示相关信息,以便你知道如何去解决它。插件安装完成后,成功安装界面将会出现:

      magento extensions install success

      插件安装完成后返回Magento后台并按需调整设置是很重要的。当然也要确保你网上店铺有正确的功能并不存在错误。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 09 Feb 2016 14:44:44 +0000
      <![CDATA[Magento2如何扩展一个布局]]> https://www.360magento.com/blog/magento2-layout-extend/ 创建一个布局扩展文件

      在Magento系统中扩展布局你只需要创建一个包含修改内容的扩展布局文件,而不是复制大量的页面布局或页面配置代码并修改你想要改变的部分。

      要添加一个扩展页面配置或通用布局文件:

      将布局文件放在如下位置:

      <theme_dir>
       |__/<Namespace>_<Module>
         |__/layout
           |--<layout1>.xml
           |--<layout2>.xml
      

      例如,自定义<Magento_Catalog_module_dir>/view/frontend/layout/catalog_product_view.xml布局,你需要在你自定义的主题中添加一个同样名字的布局,就像这样:<theme_dir>/Magento_Catalog/layout/catalog_product_view.xml

      要添加一个扩展页面布局文件:

      将文件放在如下位置:

      <theme_dir>
       |__/<Namespace>_<Module>
         |__/page_layout
           |--<layout1>.xml
           |--<layout2>.xml
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 18 Jan 2016 14:14:34 +0000
      <![CDATA[Magento2布局文件类型]]> https://www.360magento.com/blog/magento2-layout-types/ 本章内容

      对于一个特定的页面,其布局主要被两个重要的布局组件定义:页面布局文件和页面配置文件。

      一个页面布局文件定义页面线框,例如,一列布局。技术页面布局是.xml文件,定义html页面<body>区域内的结构。页面布局功能只是容器。所有的页面布局声明应在页面布局声明文件中声明。

      页面配置也是一个.xml文件。它定义详细的结构(页面头部,底部等),内容和页面元信息,包括使用的页面布局。页面配置功能包括主元素和块(尤其是类和容器)。

      我们还区分了第三类布局文件,通用布局。它们是定义内容和HTML页面组成中<body>区域详细结构的.xml文件。这些文件用于返回Ajax请求,电子邮件,HTML片段等页面。

      本文给出了每种布局文件类型的详细描述。

      页面布局

      页面布局声明页面区域内的线框,如一列布局或者两列布局。

      允许的布局指令:

      • <container>
      • <referenceContainer>
      • <move>
      • <update>

      页面布局示例:

      <Magento_Theme_module_dir>/view/frontend/page_layout/2columns-left.xml

      <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
          <update handle="1column"/>
          <referenceContainer name="columns">
              <container name="div.sidebar.main" htmlTag="div" htmlClass="sidebar sidebar-main" after="main">
                  <container name="sidebar.main" as="sidebar_main" label="Sidebar Main"/>
              </container>
              <container name="div.sidebar.additional" htmlTag="div" htmlClass="sidebar sidebar-additional" after="div.sidebar.main">
                  <container name="sidebar.additional" as="sidebar_additional" label="Sidebar Additional"/>
             </container>
          </referenceContainer>
      </layout>
      

      页面布局文件常规位置

      常规页面布局位置如下:

      • Module page layouts(模型页面布局):<module_dir>/view/frontend/page_layout
      • Theme page layouts:(主题页面布局):<theme_dir>/<Namespace>_<Module>/page_layout

      页面布局声明

      要能够使用一个布局为实际的页面进行渲染,你需要在layouts.xml中声明它。

      常规布局声明文件可能位于下面位置之一:

      • Module layout declarations(模型布局声明):<module_dir>/view/frontend/layouts.xml
      • Theme layout declaration(主题布局声明):<theme_dir>/<Namespace>_<Module>/layouts.xml

      使用<layout></layout>指令声明布局文件,如下指定:

      • <layout id="layout_file_name">例如,2columns-left.xml页面布局如下声明:<layout id = "2columns-left"/>
      • <label translate="true|false">{Label_used_in_Admin}</label>

      页面布局声明文件示例:

      <Magento_Theme_module_dir>/view/frontend/layouts.xml

      <page_layouts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/PageLayout/etc/layouts.xsd">
          <layout id="1column">
              <label translate="true">1 column
          </layout>
          <layout id="2columns-left">
              <label translate="true">2 columns with left bar
          </layout>
          <layout id="2columns-right">
              <label translate="true">2 columns with right bar
          </layout>
          <layout id="3columns">
              <label translate="true">3 columns
         </layout>
      </page_layouts>
      

      页面配置

      页面配置在一个页面布局文件中定义添加到线框的内容。一个页面配置也包含页面元信息和<head>内容。

      页面配置文件常规位置

      常规页面配置文件位于下面位置:

      • Module page configurations(模型页面配置): <module_dir>/view/frontend/layout
      • Theme page configurations(主题页面配置): <theme_dir>/<Namespace>_<Module>/layout

      页面配置结构和允许的布局指令

      下表描述了页面配置文件的指令。要查看通用布局指令请看《Magento2布局指令》

      ElementAttributesParent ofDescription
      <page></page>
      • layout = {layout}
      • xsi:noNamespaceSchemaLocation ="{path_to_schema}"
      • <html>
      • <head>
      • <body>
      • <update>
      Mandatory root element.
      <html></html>

      none

      • <attribute>
      Mandatory element.
      <head></head> none
      • <title>
      • <meta>
      • <link>
      • <css>
      • <script>
       
      <body></body> none
      • <block>
      • <container>
      • <move>
      • <attribute>
      • <referenceBlock>
      • <referenceContainer>
      • <action>
       
      <attribute>
      • name = {arbitrary_name}
      • value = {arbitrary_value}
       

      Specified for <html>, rendered like following:

      <html name="value'>

      <title>

      none none Page title

      <meta>

      • content
      • charset
      • http-equiv
      • name
      • scheme
      none  

      <link>

      • src
      • defer
      • ie_condition
      • charset
      • hreflang
      • media
      • rel
      • rev
      • sizes
      • target
      • type
      none  
      <css>
      • src
      • defer
      • ie_condition
      • charset
      • hreflang
      • media
      • rel
      • rev
      • sizes
      • target
      • type
      none  

      <script>

      • src
      • defer
      • ie_condition
      • async
      • charset
      • type
      none  

      通用布局

      通用布局定义HTML页面<body>区域内的内容和详细结构。

      通用布局文件常规位置

      常规通用布局文件位于以下位置:

      • Module generic layouts(模型通用布局):<module_dir>/view/frontend/layout
      • Theme generic layouts(主题通用布局):<theme_dir>/<Namespace>_<Module>/layout

      通用布局结构和允许的布局指令

      下表描述了页面配置文件的指令。要查看通用布局指令请看《Magento2布局指令》

      ElementAttributesParent ofDescription
      <layout></layout>
      • xsi:noNamespaceSchemaLocation="{path_to_schema}"
      • <container>
      • <update>
      Mandatory root element.
      <update>
      • handle="{name_of_handle_to_include}"
      none  
      <container>
      • <block>
      • <container>
      • <referenceBlock>
      • <referenceContainer>
      Mandatory element

      通用布局示例:

      <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
          <update handle="formkey"/>
          <update handle="adminhtml_googleshopping_types_block"/>
          <container name="root">
              <block class="Magento\Backend\Block\Widget\Grid\Container" name="googleshopping.types.container" template="Magento_Backend::widget/grid/container/empty.phtml"/>
          </container>
      </layout>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 08 Jan 2016 15:21:48 +0000
      <![CDATA[Magento主题安装]]> https://www.360magento.com/blog/magento_themes_install/ 当你选好一个主题,进入它的详细页,点击Install Now,选择Magento Connect版本(Magento1.5以上选择2.0版本,其它的保持默认的1.0),同意扩展协议并点击Get Extension Key按钮。

      magento theme extension key

      扩展密钥将会呈现出来,所以你可以选择和复制它。然后,打开Magento后台,进入System -> Magento Connect -> Magento Connect Manager。再次输入管理员登录信息并在Paste extension key to install区域粘贴密钥。最后点击Install按钮。

      magento theme install

      安装完成后返回后台,进入System -> Configuration -> Design -> Themes。在Default区域输入主题名并点击Save Config按钮。

      magento theme change

      前台页面也许没能正确地加载。原因可能是新主题的首页布局列数。你可以在CMS -> Pages中解决这个问题。一个是两列,其它的都是一列。通过点击它们的status禁用第一个和启用第二个。

      magento cms page

      现在前端页面就正确地显示新的主题了。

      magento new theme

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 04 Jan 2016 15:59:17 +0000
      <![CDATA[Magento谷歌分析设置]]> https://www.360magento.com/blog/magento_google_analytics/ 谷歌分析是谷歌的一项免费服务,它可以让网站的拥有者和管理员监控他们网站的流量和转化率。Magento支持两种类型的跟踪:

      • 页面视图跟踪:列出访客的链接起源,即访客是从哪个链接进入你的店铺的。
      • 电子商务跟踪:列出达成交易的客户极其购买的商品。

      首先,你需要在http://www.google.com/analytics/sign_up.html注册。你将收到一个谷歌分析帐号。把它记下来,因为你会在Magento设置时需要它。

      现在,你需要在你的店铺里配置谷歌分析。登录你的Magento后台,进入System -> Configuration -> Sales -> Google API,展开Google Analytics区域。

      magento google analytics.jpg

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 31 Dec 2015 15:05:57 +0000
      <![CDATA[Magento2布局指令]]> https://www.360magento.com/blog/magento2-xml-instructions/ 本章内容

      改变布局是Magento中自定义页面布局的两种方式之一(第二种方式是改变模板文件)。改变页面线框,修改页面布局文件;所有其它自定义的设置在页面配置或通过布局文件来执行。

      使用布局指令来:

      • 移动页面元素到另一个父元素
      • 添加内容
      • 删除页面元素

      对于所有类型的布局文件来说基础指令集是相同的。这篇文章描述这些基本指令;至于如何在特定布局文件类型中使用的细节,请参阅下一篇文章。

      常用布局指令

      使用下面的布局指令来自定义你的布局:

      • <block>
      • <container>
      • beforeafter属性
      • <action>
      • <referenceBlock><referenceContainer>
      • <move>
      • <update>
      • <argument>

      <block>

      定义一个块

      详细信息:块是页面输出呈现出不同内容的单元-一片信息,一个用户界面元素-任何客户视觉上可见的东西。块使用模板来生成HTML。模块的例子有:分类列表,迷你购物车,产品标签和产品列表。

      属性描述必须性
      class(类) 生成特定块的类名,这个类对应一个实际输出的块。 类名 是的
      name(名字) 用于处理分配到该属性的块,在每个生成的页面中名字必须是唯一的。 如果没有指定就会自动以 ANONYMOUS_n的格式分配一个名字 0-9, A-Z, a-z, 下划线 (_), 点(.),破折号(-)。必须以字母开头。区分大小写。
      before(在……之前) 用于块的位置。在相同父元素下,出于一个元素之前。在这个值中元素的名字或别名是指定的。使用破折号(-)将元素放在其他 元素之前。详细信息请看before和after属性 可能值:元素名或破折号(-)
      after(在……之后) 用于块的位置。在相同父元素下,出于一个元素之后。在这个值中元素的名字或别名是指定的。使用破折号(-)将元素放在其他 元素之后。详细信息请看before和after属性 可能值:元素名或破折号(-)
      模板 模板用来呈现该属性分配的块的功能。 模板文件名
      as(别名) 作为父元素范围内的标识 0-9,A-Z,a-z,下划线(_),点(.),破折号(-)。区分大小写。
      cacheable(可缓存) 定义块元素是否可缓存。这可以用于卡发目的并为页面动态元素提供服务 true(真)false(假)

      要传递参数,使用<argument></argument>指令。

      <container>

      用于支持其它元素(如块和容器)的没有内容的结构。

      详细信息:在视图输出生成时容器渲染子元素。它可以为空或包含一组<container><block> 元素。

      属性描述必须性
      名字 用于处理分配到该属性的容器,在每个生成的页面中名字必须是唯一的。 0-9, A-Z, a-z, 下划线 (_), 点(.),破折号(-)。必须以字母开头。区分大小写。
      标签 用于在浏览器展示的任意名字 任何
      before 用于块的位置。在相同父元素下,出于一个元素之前。在这个值中元素的名字或别名是指定的。使用破折号(-)将元素放在其他 元素之前。详细信息请看before和after属性 可能值:元素名或破折号(-)
      after(在……之后) 用于块的位置。在相同父元素下,出于一个元素之后。在这个值中元素的名字或别名是指定的。使用破折号(-)将元素放在其他 元素之后。详细信息请看before和after属性 可能值:元素名或破折号(-)
      as(别名) 作为父元素范围内的标识 0-9,A-Z,a-z,下划线(_),点(.),破折号(-)。区分大小写。 no
      output 定义是否输出根元素。如果指定元素将被添加到输出列表。(如果没有指定,父元素渲染他的子元素) toHtml外的任何值。推荐值为1
      htmlTag(html标签) 输出参数。如果指定,输出被抱进指定的Html标签中   任何可用的html5标签
      htmlId 输出参数。如果指定,参数值被添加到包着的元素。如果没有包着的元素,该属性就没有效果。 任何可用的html5标签<id>值。
      htmlClass(html类) 输出参数。如果指定,参数值被添加到包着的元素。如果没有包着的元素,该属性就没有效果。 任何可用的html5标签<class> 值。

      布局中使用的示例:

      ...
      <container name="div.sidebar.additional" htmlTag="div" htmlClass="sidebar sidebar-additional" after="div.sidebar.main">
          <container name="sidebar.additional" as="sidebar_additional" label="Sidebar Additional"/>
      </container>
      ...
      

      这将在页面布局中新加一行

      before和after属性

      为帮助你按特定的顺序排列元素以满足设计,搜索引擎优化,实用或其它要求,Magento提供了beforeafter布局属性。

      这些可选属性可被用在布局XML文件中,在公用的父元素中控制顺序。下面的表格给出你使用beforeafter属性后的结果。第一张表使用一个块作为定位元素。

      属性描述
      before 破折号(-) 在父节点中显示在其它元素之前。
      before 元素名字 块在该名字的元素之前显示。
      before 空值或元素名不存在 使用值after。如果值为空或者元素名不存在则被视为未被定位。
      after 破折号(-) 在父节点中显示在其它元素之后。
      after 元素名字 块在该名字的元素之后显示。
      after 空值或元素名不存在 使用值before。如果值为空或者元素名不存在则被视为未被定位。

      示例:

      情况结果
      beforeafter属性都存在 after优先。
      Both before and after属性都不存在或为空 元素被视为未定位。其它元素按指定位置定位。未被定位的元素随机出现在与其它元素定位不冲突的位置。
      几个元素属性值before or after被设置为破折号(-) 所有元素显示在顶部 (或底部,属性为after时),但该组顺序未被定义。
      The beforeafter属性值中的元素不位于与该元素不在同一父节点中 元素处在一个随机位置但不与正确的元素位置冲突

      <action>

      <action>指令已被废弃。如果方法生成允许,使用<argument>来访问<block><referenceBlock>的公共API。

      调用块API的公共方法:

      详细信息:在块的生成过程中设置某个方法的执行。<action>结点必须位于块的结点范围。

      示例:

      
      <block class="Magento\Module\Block\Class" name="block">
          <action method="setText">
              <argument name="text" translate="true" xsi:type="string">Text</argument>
          </action>
          <action method="setEnabled">
              <argument name="enabled" xsi:type="boolean">true</argument>
          </action>
      </block>
      

      <action>子节点被翻译成块的方法参数。子节点的名称是任意的。如果<action>下有多个同名的子节点,那么这些子节点会作为数组被传递。

      在上面的例子中<arg1>的值作为和<arg2>的值组成的array('one', 'two')中的第一个参数被传递。所有可用的方法取决于块的实现。

      属性描述必须性
      method 块的公用方法类名,在块的生成过程中被调用。 块方法名

      要传递参数,使用<argument></argument>指令。

      <referenceBlock>和<referenceContainer>

      使用<referenceBlock><referenceContainer>来更新对应的<block><container>。例如,你如果使用<referenceBlock name="right">,那么你指向的目标块就是<block name="right">

      属性描述必须性
      remove(移除) 允许移除或取消元素的输出,如果一个容器被移除,其子元素也被去除。 真/假
      display(显示) 允许禁用特定块或容器及其孩子的渲染(都是通过引用直接设置)。块/容器及它们的孩子各自的PHP对象仍然被生产并可供操作 。 真/假

      remove属性是可选的,默认值为false。在你的布局中设置remove属性值为false来取消块或容器的输出。例如:

      <referenceBlock name="block.name" remove="true" />

      display属性是可选的,默认值为true。你可以在你的布局中重写这个值。当remove属性为true时,display属性被忽略。例如:

      <referenceContainer name="container.name" display="false" />

      <ltmove>

      设定声明的块或元素以特定的顺序作为另一个元素的子元素。

      示例:

      <move element="name.of.an.element" destination="name.of.destination.element" as="new_alias" after="name.of.element.after" before="name.of.element.before"/>
      
      • 如果被移动的元素未被定义,则<move>被跳过。
      • 如果as属性没有被定义,使用现有的元素别名。如果值不可用则用那么值来代替。
      • 在布局生成过程中<move>指令在<remove>指令之前执行。这意味着任何元素移动到预定位置后都将被移除。
      属性描述必须性
      element(元素) 要移动的元素的名称。 元素名
      destination(目的地) 目标父元素的名称 元素名
      as(别名) 元素在新位置的别名。 0-9,A-Z,a-z,下划线(_),点(.),破折号(-)。区分大小写。
      after | before 指定元素相对同级元素的位置。使用破折号(-)时元素在其它元素之后或之前。如果省略该值则元素在其它同级元素之后。 元素名

      <update>

      包含一个特定的布局文件,如下使用:

      <update handle="{name_of_handle_to_include}"/>

      指定的句柄被包括并递归执行。

      <argument>

      用于传递参数。

      属性描述必须性
      名称 参数名 唯一
      xsi:type 参数类型 string|boolean|object|number|null|array
      translate   真|假

      要传递多个参数时,使用下面的指令:

      <arguments>
         <argument></argument>
         <argument></argument>
         ...
      </arguments>
      

      传递的参数为数组时,使用下面的指令:

      <argument>
         <item></item>
         <item></item>
         ...
      </argument>
      

      在布局中设置的参数值可以在模块中使用get{ArgumentName}()has{ArgumentName}()方法调用。无论是否有值被设置,最终返回一个布尔值。从name属性获取{ArgumentName}的方法是:获取<argument name="some_string">值的方法名是getSomeString()。例如:在app/code/Magento/Theme/view/frontend/layout/default.xml布局文件中设置css_class的值:

      ...
      <arguments>
          <argument name="css_class" xsi:type="string">header links</argument>
      </arguments>
      ...
      

      app/code/Magento/Theme/view/frontend/templates/html/title.phtml文件中使用css_class的值:

      ...
      $cssClass = $this->getCssClass() ? ' ' . $this->getCssClass() : '';
      ...
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 30 Dec 2015 16:53:01 +0000
      <![CDATA[Magento通讯管理]]> https://www.360magento.com/blog/magento_newsletter/ 告诉你的客户最新促销和折扣活动是很重要的。Magento通讯功能允许店铺管理员给订阅客户发送这些信息。 首先你需要开启客户同意接收订阅,该功能可以在Magento后台System-> Configuration-> Customers-> Newsletter区域被打开。展开Subscription Options区域,修改Need to Confirm值为Yes

      enable magento newsletter

      客户可以退订新闻。管理员可以通过下拉列表菜单定义退订电子邮件的发件人和模板。对于成功订阅和确认邮件发送者和模板也可以进行同样的操作。你可以使用同一个,也可以根据自己需求自定义它们。点击保存以确认修改。

      下一步,你应该设置通讯模板。进入后台Newsletter -> Newsletter Templates -> Add New Template

      magento new newsletter template

      输入模板名,邮件将被送达的对象,发送者姓名和邮箱以及通讯模板内容。填写完毕后可点击Preview Template进行预览,点击Save Template按钮保存模板。模板将被添加到对应的列表,你将能够编辑它。

      当你计划发送信息给很多收件人时,你应该把列表分成小部分。你可以通过后台Newsletter -> Newsletter Templates-> Action -> Queue Newsletter来配置和管理这个功能。

      magentoqueue newsletter

      Queue Date Start区域填写邮件发送的时间。这些信息将小批量地离开电子邮件服务器。确认其它选项,准备好后点击Save Newsletter按钮。

      magento newsletter queue information

      你可以找到不同的通讯报道。在后台Newsletter-> Newsletter Queue你可以监视通讯队列的进展。你可以在后台Newsletter -> Newsletter Subscribers查看订阅邮件的客户列表。你可以手动取消它们。后台Newsletter-> Newsletter Problem Reports区域显示在通讯发送过程中出现的错误,你可以采取必要的步骤来解决它们。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 29 Dec 2015 16:04:18 +0000
      <![CDATA[magento客户管理]]> https://www.360magento.com/blog/magento_customer_manager/ 新客户可以通过首页My Account或者下单过程来注册到你的网站。他们应该点击Create an Account按钮并填写详细信息:

      magento customer create

      你可以通过后台Customers区域来创建新客户或者管理已有客户:

      magento customer manager

      点击Edit按钮可改变客户详细信息。你可以改变所有的客户详细信息,包括用户名和密码,地址,监控订单,购物车,收藏产品,产品评价和标签,订阅的管理。

      magento customer edit

      你可以通过后台Customers->Customer Groups来创建和管理客户组:

      magento customer group manager

      你可以从后台Customers->Online Customers来观察在线的用户。你将要发送个客户的订阅信息在后台Newsletter处被撰写和管理。

      magento newsletter

      你可以创建模板,管理订阅信息邮件传出的队列,订阅发送对象和问题报告的检查。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 28 Dec 2015 15:23:37 +0000
      <![CDATA[Magento2定位模板,布局和样式]]> https://www.360magento.com/blog/magento2-locate-files/ 本章内容

      当你创建一个Magento主题时,你可能需要为默认主题和模型视图文件创建重写文件。那么在此之前,你必须决定Magento使用的是哪个模板,布局和样式文件。本文就描述如何做到这一点。

      定位模板

      要定位特定部分对应的前端或后台模块,你可以使用Magento内置的模板提示。

      开启模板提示:

      1. 点击Stores > Configuration > ADVANCED > Developer
      2. 在左上角的Scope下拉列表里选择你想要开启模板提示的视图。
      3. Debug标签里,设置Template Path Hints for storefrontYes。要开启后台通道提示,设置Template Path Hints for AdminYes
      4. 保存更改,点击右上角的Save Config
      magento2 templates path hint

      现在,你已经开启了模板提示,刷新你想要修改的页面,查看模板文件路径或者模板提示显示的文件。

      例如,开启模板提示后的产品详细页看起来是这样的:

      magento2 category page hint

      在本示例中,迷你购物车页面元素被定义在<Magento_Checkout_module_dir>/view/frontend/templates/cart/minicart.phtml模板。

      magento2 mini cart page

      (模板名称在元素上面)

      开启模板提示的后台Customer页面看起来是这样的:

      magento2 admin template hints

      另外,你可以在文件系统中通过搜索系统生成的标题,CSS类名,块标题,标签或链接文字来找到对应的模块。例如,使用一个浏览器调试工具,你可以看到迷你购物车块的css类是minicart-wrapper

      magento2 minicart block css

      在app目录下搜索“minicart-wrapper”,得到的.phtml文件是app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml。由于不推荐修改默认文件,如果你想要修改这个模板就需要添加重写文件。重写模板的细节将会在后面的《自定义主题模板》中讲解。

      定位布局

      和模板一样,布局被存储在每个模型基础文件中。根据你感兴趣的元素位于哪个模板的模型,你可以轻松地定位布局文件。要定位模板,你可以使用模板提示或者在app目录下使用文本搜索。

      在你决定模型以后,你可以在下面的位置中搜索布局:

      1. <current_theme_dir>/<Namespace>_<Module>/layout/
      2. <parent_theme(s)_dir>/<Namespace>_<Module>/layout/
      3. <module_dir>/frontend/layout/
      4. <module_dir>/view/base/layout/

      这里没有直接的算法来发现准确的布局文件,但是大部分情况下,布局文件名是自我描述性的。你也可以搜索它们提到的对应模块。

      示例:

      比方说,当Blank主题被Magento应用为店铺视图时,你要定位在前端显示迷你购物车的布局文件。

      使用模板提示我们发现对应的模板是app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml,由路径我们发现它是属于Magento_Checkout模型的。

      让我们根据回退计划来寻找布局:

      1. 检查app/design/frontend/Magento/blank/Magento_Checkout/layout,在这个目录中搜索模板名称“minicart.phtml”。没有找到相匹配的文件,所以我们进行回退级别的下一级,父主题布局。
      2. 在主题配置文件theme.xml中我们可以找到父主题的信息,父主题的名字在<parent></parent>节点指定。在app/design/frontend/Magento/blank/theme.xml中没有<parent>节点,这意味着Blank主题没有父主题。所以我们该搜索回退等级的下一级:模型布局。
      3. Magento_Checkout布局位于app/code/Magento/Checkout/view/frontend/layout/。在这个目录中搜索“minicart.phtml”,我们找到了要寻找的布局app/code/Magento/Checkout/view/frontend/layout/default.xml

      在定位了必要的布局文件,你可以在你的主题文件夹中创建对应名字的主题来重写或者扩展主题的内容。

      定位样式

      要定位一个被应用到特定元素的CSS规则,找到包含这个元素页面的模板。或者你可以使用浏览器调试工具来定位类名。找到类名之后,在主题和模型样式目录中使用文本搜索来定位要找的.less.css文件。根据下面的回退计划来搜索:

      1. 主题样式 <current_theme_dir>/web/css/
      2. 模型主题样式 <current_theme_dir>/<Namespace>_<Module>/web/css/
      3. 父主题样式 <parent_theme_dir>/web/css/
      4. 前端模型样式 <module_dir>/view/frontend/web/css/
      5. base模型样式 <module_dir>/view/base/web/css/

      示例:

      当Blank主题被Magento应用为店铺视图时,让我们找出用于前端显示迷你购物车的CSS类。 在迷你购物车模板app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml中最高级的元素有minicart-wrapper类。所以,我们根据回退计划搜索“minicart-wrapper”。

      1. app/design/frontend/Magento/blank/web/css搜索,返回无结果。
      2. 搜索app/design/frontend/Magento/blank/Magento_Checkout/web/css。“minicart-wrapper”样式被定义在app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less

      在确定定义类的.css.less文件后,你可以在你自定义的.css.less中重写默认的类。详细的信息会在后面的CSS文章中讲解。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 27 Dec 2015 13:02:59 +0000
      <![CDATA[Magento2主题继承]]> https://www.360magento.com/blog/magento2-theme-inherit/ 本章内容

      主题继承使你可以轻松地扩展主题和减少维护工作。你可以使用现有的主题作为定制开发的基础,或者细微的店面设计更新,像节假日装饰。你可以添加重写和扩展文件,而不是复制原主题文件做修改。

      主题继承的级别是不限定的。

      主题继承是基于回退机制(保证如果一个视图文件没有在当前主题中被找到,系统就会在祖先主题,模型视图文件或者库中搜索)。 回退的顺序与静态文件(CSS,JavaScript,字体和图像),其它类型主题文件略有不同。本文描述每种主题文件的回退并提供如何重写祖先主题和模型设计的概念。

      有关开发主题组件的全面信息,请参阅Magento2教程的后续章节。

      设置一个父主题

      一个父主题在子主题的theme.xml声明文件中被指明。

      例如:OrangeCo的Orange主题继承自Magento的Blank主题。继承被声明在app/design/frontend/OrangeCo/orange/theme.xml,代码如下:

      <theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
           <title>Orange</title>
           <parent>Magento/blank</parent> 
           <media>
               <preview_image>media/preview.jpg</preview_image> 
           </media>
      </theme>
      

      父主题和子主题可以属于不同的供应商。例如,你自定义的主题可以继承Magento的Blank主题。

      重写静态资产

      静态资产,或静态视图文件,是样式,JavaScript,图像和字体。

      要自定义父主题、模型视图或库文件里的视图文件,你可以通过添加一个相同名字的文件到相关位置来重写它们。特定的目录(系统在回退过程中搜索的地方)取决于模型内容是否对文件已知。下面是对两种情况的描述:

      如果模型内容没有为文件做定义:

      1. 当前主题静态文件:<theme_dir>/web/
      2. 祖先静态文件,递归,直到到达一个没有父类的主题:<parent_theme_dir>/web/
      3. 库静态视图文件:lib/web/

      如果模型内容为文件做了定义:

      1. 当前主题模型静态文件:<ttheme_dir>/<Namespace>_<Module>/web/. 例如:app/design/frontend/OrangeCorp/orange/Magento_Catalog/web/
      2. 祖先静态文件,递归,直到到达一个没有父类的主题:<parent_theme_dir>/<Namespace>_<Module>/web/
      3. 前端模型静态视图文件:<module_dir>/view/frontend/web/
      4. base区域模型静态视图文件:<module_dir>/view/base/web/

      示例:

      一家名为OrangeCo的公司有一个名为Orange的主题。主题文件位于:app/design/frontend/OrangeCo/orange。Orange继承自Magento的Blank主题。

      让我们想像一下,OrangeCo需要添加一些冬季假期装饰。所以它创建以一个继承自Orange的新主题orange_winter,位于app/design/frontend/OrangeCo/orange_winter。在Orange主题中底部背景图位于app/design/frontend/OrangeCo/orange/web/images/background.jpg

      magento2 theme background1

      OrangeCo希望它被替换成一个节日的背景。于是一个有同样名字的新的背景图被放在app/design/frontend/OrangeCo/orange_winter/web/images/background.jpg

      当Orange Winter主题被应用,新的节日图片就会重写Orange主题中的图片,那么前台效果就是这样:

      magento2 theme background2

      重写模板

      模板的回退计划如下(模型内容对它们来说是已知的):

      1. 当前主题模块:<theme_dir>/<Namespace>_<Module>/templates
      2. 祖先主题模块,递归,直到到达一个没有父类的主题:<parent_theme_dir>/<Namespace>_<Module>/templates
      3. 模型模板: <module_dir>/view/frontend/templates

      所以如果你需要自定义一个特定的模板,你需要创建一个同样名字的模板放在主题模型文件../templates/<path_to_template> 目录下。其中,<path_to_template>是原始模板的路径。

      例如:你想要重写<Magento_Catalog_module_dir>/view/frontend/templates/category/widget/link/link_block.phtml,那么<path_to_template>就是category/widget/link/

      示例:在默认情况下,根据模型文件,迷你购物车中的产品是在Checkout按钮之下的:

      magento2 theme minicart1

      顺序是在<Magento_Checkout_module_dir>/view/frontend/templates/cart/minicart.phtml模型文件中被定义的。Blank主题没有重写这个模板。OrangeCo希望他们的产品展示在Go to Checkout按钮之前。他们需要在Orange主题文件夹内为对应的模型添加一个重写模板:app/design/frontend/OrangeCo/orange/Magento_Checkout/templates/cart/minicart.phtml。注意,主题templates目录中的模块路径与模型相对应。改变顺序之后,OrangeCo的购物车看起来是这样的:

      magento2 theme minicart2

      你可以在之后的文章中找到详细的代码和其它任务。

      扩展布局

      布局进程机制不涉及回退。系统按下面的顺序收集主题文件:

      1. 当前主题布局:<theme_dir>/<Vendor>_<Module>/layout/
      2. 祖先主题布局,递归,直到到达一个没有父类的主题:<parent_theme_dir>/<Vendor>_<Module>/layout/
      3. 前端区域的模型主题:<module_dir>/view/frontend/layout/
      4. Base区域的模型主题:<module_dir>/view/base/layout/

      与模板、图片不同,主题不仅能被重写还能被扩展。推荐的自定义布局是通过创建主题扩展布局文件来扩展它。 要添加一个扩展布局文件:把你自定义的布局文件放在:<theme_dir>/<Vendor>_<Module>/layout/目录下。

      例如:

      OrangeCo决定移除<Magento_Theme_module_dir>/view/frontend/layout/default.xml中定义的底部“Report bugs”链接。要实现它,他们添加了一个扩展主题文件在app/design/frontend/OrangeCo/orange/Magento_Theme/layout/default.xml

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <body>
              <remove name="report.bugs"/>
         </body>
      </page>
      

      更多关于主题扩展的知识将会在《扩展主题》中提到。

      重写布局

      虽然不推荐重写布局,但这也是特定自定义任务的一种解决方式。要重写祖先主题的布局文件:

      • 创建同样名字的布局文件到<theme_dir>/<Vendor>_<Module>/layout/override/theme/<Vendor>/<ancestor_theme>目录下

      要重写模型布局文件(base布局)

      • 创建同样名字的布局文件到<theme_dir>/<Vendor>_<Module>/layout/override/base

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 25 Dec 2015 15:57:06 +0000
      <![CDATA[为Magento2主题配置图片性能]]> https://www.360magento.com/blog/magento2-images-properties/ 为Magento2主题配置图片性能

      Magento2中用于前台的产品图片性能都被存储在view.xml配置文件中。本文提供所有的可用性能细节及配置方法。

      在view.xml中配置图片性能

      view.xml通常位于主题的:

      <theme_dir>/etc/view.xml

      例如,view.xml在Magento Blank主题中的位置是:

      app/design/frontend/Magento/blank/etc/view.xml

      view.xml中,图片性能被配置在<images module="Magento_Catalog">元素内:

      <images module="Magento_Catalog">
      ...
      <images/>
      

      每种被图片性能配置的类型图片是通过<image>元素的idtype属性定义的:

      <images module="Magento_Catalog">
      	<image id="unique_image_id" type="image_type">
      	...
      	</image>
      <images/>
      

      下面的表格描述属性的详情:

      属性类型描述
      id(标识) string(字符串)

      图片标识,主题中是唯一的

      可以是任何值,但在Magento主题中ID是有意义的并描述图像的位置。

      例如,购物车中的交叉销售产品图片<code>ID是cart_cross_sell_products.

      ID被用在.phtml模版来给特定网页特定位置的图片定义类型和性能。

      type(类型) string(字符串) 通过指定的<code>ID来定义图片的类型。允许值为:
      • image - 对应Magento2后台中的Base Image
      • small_image - 对应Magento2后台中的Small Image
      • swatch_image - 对应Magento2后台中的Swatch Image
      • swatch_thumb - 对应Magento2后台中的Swatch Image
      • thumbnail - 对应Magento2后台中的Thumbnail Image
      下面的图片说明了Magento2后台中的各种图片角色:
      magento2 cache

      图片性能通过对应的元素而被定义,例如:

      <images module="Magento_Catalog">
          <image id="unique_image_id" type="image">
              <width>100</width> <!-- Image width in px --> 
              <height>100</height> <!-- Image height in px -->
          </image>
      </images>
      

      下面表格是所有可配置性能的列表:

      元素属性值类型描述属性值必须性
      width 整型 以像素为单位的图像宽度。 可选填
      height 整型 以像素为单位的图像高度。 可选填
      constrain 布尔型 如果被设置为true时,当图像小于配置值时不会扩大。默认值为:true 可选填
      aspect_ratio 布尔型 如果被设置为true,图片比例不会改变即使配置中需求。默认值为:true. 可选填
      frame 布尔型 如果被设置为true, 图片不被裁剪。默认值为:true。只有当aspect_ratio被设置为 true时才可被应用。 可选填
      透明度 布尔型 如果被设置为true,图片的透明背景被保存。如果设置为false,图片背景为白色(默认的)。你可以使用 background字段来设置背景色。默认值为:true 可选填
      背景 数组 图片的背景色。如果transparency被设置为true时,不被应用到透明背景图。 可选填

      目录图片大小调整命令

      Magento_Catalog模型提供调整所有产品图片的Magento CLI命令。调整后的图片被存储在/pub/media/catalog/product/cache目录下。

      catalog:images:resize命令没有选项和参数。

      基本语法:bin/magento catalog:images:resize

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 21 Dec 2015 14:36:30 +0000
      <![CDATA[在Magento2后台应用和配置一个主题]]> https://www.360magento.com/blog/theme-apply-configure/ 在Magento2后台应用和配置一个主题

      本文描述如何将一个主题应用到你的商店,禁用缓存和添加一个与主题无关的logo。

      禁用系统缓存

      当Magento系统缓存开启时,你必须每次都清理缓存来查看你的设计给前端带来的改变。为了避免这种情况,在更改设计的同时禁用某些系统缓存。你需要要这么做:

      1. 后台进入 System > Tools > Cache Management
      2. 选择Layouts, Blocks HTML output, View files fallback, View files pre-processing and Page Cache cache types。
      3. Action选项中选择Disable并点击Submit。选择的缓存类型会显示成红色的DISABLED。
      magento2 cache

      如果你第二次应用一个主题,你可能需要手动清除pub/static/frontend/<Vendor>/<theme>目录。这个目录存储已发布的静态文件。

      应用一个主题

      在将你的主题添加到文件系统以后,你可以将它应用到你的店铺。去应用一个主题:

      1. 进入后台 CONTENT > Design > Themes 。确认你的主题在主题列表里。
      2. 进入 Stores > Configuration > Design
      3. 在Scope下拉框里选择你主题想要应用的店视图。
      4. Design Theme 标签的 Design Theme 下拉框里选择你最新创建的主题。
      5. 点击 Save Config
      6. 查看效果,重载前端页面。

      如果在你的Magento后台面板中缓存是可用的,那么你必须清理缓存来查看效果。你可能还需要手动清理pub/static/frontend文件夹中已发布的静态文件。

      添加一个设计例外

      你可以为特定的用户代理设置指定的主题,而不用创建一个独立的店铺视图。要添加设计例外:

      1. 进入后台 CONTENT > Design > Themes 。确认你的主题在主题列表里。
      2. 进入 Stores > Configuration > Design
      3. Scope下 拉框里选择你主题想要应用的店视图。
      4. 点击 Design Theme 标签 User-Agent Exceptions 旁的 Add
      5. Search String 框里指明用户代理使用普通字符串或常规异常(PCRE)。在 Design Theme 下拉列表里选择与代理匹配的主题。
      6. 点击Save Config

      如果在你的Magento后台面板中缓存是可用的,那么你必须清理缓存来查看效果。

      添加一个与主题无关的logo

      你可能想要设置一个永久性的店铺logo,不论应用哪个主题它都会显示在店铺前端。要添加一个与主题无关的永久性logo

      1. 进入后台Stores > Configuration > Design
      2. Scope下拉框里选择你主题想要应用的店视图。
      3. DesignGeneral区域展开Header标签。
      4. Logo Image处选择在文件系统中存储的logo图片。
      5. 上传文件。
      6. 点击Save Config

      你在这里添加的logo被存储在/pub/media/logo/default/目录下。

      如果在你的Magento后台面板中缓存是可用的,那么你必须清理缓存来查看效果。

      要删除永久性logo,只需到相同位置,点击右侧的Delete即可。

      清除缓存

      如果在你的Magento后台面板中缓存是可用的,那么在你应用主题,添加主题例外,添加logo以及执行其他任务后都需要清理缓存。会有一条系统信息提醒你,无效的缓存类型应该被刷新。

      1. 点击System > Cache Management
      2. 清除无效的缓存类型。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 19 Dec 2015 14:38:28 +0000
      <![CDATA[Magento2主题结构]]> https://www.360magento.com/blog/magento2-theme-structure/ Magento2主题结构

      店面的主题通常位于app/design/frontend/<Vendor>(供应商)/之下。虽然在技术上它们可以放在其它目录。例如Magento2的内置主题在vendor/magento/theme-frontend-<theme_code>之下,这是因为Magento2的实例是从Composer部署的。

      每个主题必须存储在单独的目录:

      app/design/frontend/<Vendor>/
      ├── <theme1>
      ├── <theme2>/
      ├── <theme3>
      ├--...
      

      主题组件

      Magento的主题目录结构通常是这样的:

      <theme_dir>/
      ├── <Vendor>_<Module>/ 
      │	├── web/
      │	│	├── css/
      │	│	│	├── source/
      │	├── layout/
      │	│	├── override/
      │	├── templates/
      ├── etc/
      ├── i18n/ 
      ├── media/
      ├── web/
      │	├── css/
      │	│	├── source/ 
      │	├── fonts/
      │	├── images/
      │	├── js/
      ├── composer.json 
      ├── registration.php 
      ├── theme.xml 
      

      让我们仔细看看每一个特定的子目录。

      目录必须性描述
      /<Vendor>_<Module> 非必须 指定模型的样式,布局和模板.
      /<Vendor>_<Module>/web/css/source 非必须 指定模型的样式(.css或.less)。一般模型样式在module.less中,挂件(widgets)的样式在 widgets.less中。
      /<Vendor>_<Module>/layout 非必须 扩展默认模型或父主题的布局文件
      /<Vendor>_<Module>/layout/override/base 非必须 重写默认模型布局的布局文件
      /<Vendor>_<Module>/layout/override/<parent_theme> 非必须 重写父主题中模型布局的布局文件
      /<Vendor>_<Module>/templates 非必须 该目录包含重写默认模型模版或父主题模版的主题模板。自定义模版也在该目录下。
      /etc/view.xml 对单个主题必须, 若有父主题则为非必须 该文件包含店铺前端产品图片和缩略图的配置。
      /i18n 非必须 带有翻译的.csv文件
      /media 必须 该目录包含一个主题预览(你主题的一张截图)。
      /web 非必须 可被前端直接读取的静态文件
      /web/css/source 非必须 该目录包含主题less配置文件(从Magento UI库里调用全局文件),和theme.less(重 写默认变量值)
      /web/css/source/lib 非必须 重写UI库的视图文件存储在lib/web/css/source/lib
      /web/fonts 非必须 主题字体。
      /web/images 非必须 主题中使用的图片。
      /web/js 非必须 主题JavaScript文件。
      /composer.json 非必须 描述主题依赖关系和一些元信息。如果你的主题是composer包的话,就在这里。
      /registration.php 必须 将你的主题注册到系统。
      /theme.xml 必须 由于该文件声明一个主题作为系统部件,所以它是强制性的。它包含基本元信息,如主题名和父主题名(主题继承自已有主题)。该文件让Magento识别你的主题。

      主题文件

      除了配置文件和主题的元数据文件,所有主题文件分为以下两类:

      • 静态视图文件
      • 动态视图文件

      静态视图文件

      一组是由服务器返回到浏览器,不进行任何处理的主题文件,被称为一个主题的静态文件。

      静态文件可以位于一个主题目录如下:

      <theme_dir>/
      ├── media/
      ├── web
      │	├── css/ (except the "source" sub-directory)
      │	├── fonts/
      │	├── images/
      │	├── js/
      

      静态文件和其他主题文件之间的主要区别是,静态文件出现在网页作为引用的文件,而其它主题文件参加页面生成,但并未明确地被引用。

      静态视图的文件可以通过从店面的直接链接进行访问,以此与公共主题文件区分开。

      动态视图文件

      被服务器处理或执行用来返回结果给客户的视图文件。它们是: .less 文件,模板(templates),布局(layouts)。 动态视图文件在一个主题目录中的位置,如下所示:

      <theme_dir>/
      ├── Magento_<module>/ 
      │	├── web/
      │	│	├── css/
      │	│	│	├── source/
      │	├── layout/
      │	│	├── override/
      │	├── templates/
      ├── web/
      │	├── css/
      │	│	├── source/
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 18 Dec 2015 14:05:26 +0000
      <![CDATA[创建magento2主题]]> https://www.360magento.com/blog/magento2-theme-create/ 创建一个主题

      本文讨论如何创建一个主题,怎么为主题添加一个logo,如何定义图片尺寸。

      文章内容

      创建一个主题目录

      为你的主题创建目录:

      1.进入/app/design/frontend.

      2.根据你供应商的名字创建一个新的目录/app/design/frontend/

      3.在vendor目录下,根据你的主题创建一个目录

      /app/design/frontend/
      ├── <Vendor>/
      │   │   ├──...<theme>/
      │   │   │   ├── ...
      │   │   │   ├── ...
      

      文件夹名称通常匹配主题代码的命名:供应商认可的任何字幕数字字符集。该公约仅仅是一个建议,并未阻止以另一种方式命名。

      声明你的主题

      在创建了主题目录以后,你必须创建包含至少主题名和父主题名(如果主题继承自一个主题)的theme.xml。你也可以指定主题预览图的存储位置。

      1.添加或者拷贝已有的theme.xml到你的主题目录app/design/frontend//下。

      2.用下面的示例来配置theme.xml

      <theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
           <title>New theme <!-- your theme's name -->
           <parent>Magento/blank</parent> <!-- the parent theme, in case your theme inherits from an existing theme -->
           <media>
               <preview_image>media/preview.jpg</preview_image> <!-- the path to your theme's preview image -->
           </media>
       </theme>
      

      为你的主题写一个Composer包(可选)

      Magento默认的主题被创建为Composer包。要把你的主题写成一个包,添加一个composer.json文件到主题目录下并在包服务器上注册这个包。默认的公共包装服务器https://packagist.org/。

      composer.json

      提供主题相关信息。下面是一个主题code>composer.json的示例:

      
      {
          "name": "magento/theme-frontend-luma",
          "description": "N/A",
          "require": {
              "php": "~5.5.0|~5.6.0|~7.0.0",
              "magento/theme-frontend-blank": "100.0.*",
              "magento/framework": "100.0.*"
          },
          "type": "magento2-theme",
          "version": "100.0.1",
          "license": [
              "OSL-3.0",
              "AFL-3.0"
          ],
          "autoload": {
              "files": [
                  "registration.php"
              ]
          }
      }
      

      添加registration.php

      要在系统中注册你的主题,你需要用下面的内容在你的主题目录下创建一个registration.php

      <?php
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */
      \Magento\Framework\Component\ComponentRegistrar::register(
          \Magento\Framework\Component\ComponentRegistrar::THEME,
          'frontend/<Vendor>/<theme>',
          __DIR__
      );
      

      这里的是你供应商的名字,theme是你主题的名字。你可以查看Luma主题的registration.php文件。

      配置图片

      产品图片大小和其它店铺前端性能在view.xml里被配置。它需要一个主题,但是否有父主题都可。 如果你主题里的产品图片与父主题不同,或者你的主题没有继承任何主题,用下面的步骤添加一个view.xml

      1.以可以创建文件夹权限的用户(通常情况下,是Magento的文件系统的所有者)登录到Magento服务器中。

      2.在你的主题目录下创建etc文件夹

      3.从已有主题中拷贝view.xml文件(例如,从Blank主题)到你主题的etc文件夹中。

      4.在view.xml中配置所有店铺前端产品图片尺寸。例如,你可以指定分类网格视图产品图片为250x250像素,相应的配置会是这样:

      ...
          <image id="category_page_grid" type="small_image">
              <width>250</width>
              <height>250</height>
          </image>
      ...
      

      创建静态文件目录

      你的主题将包含几种静态文件:样式,字体,JavaScript和图片。每种类型的图片都被存储在web目录下的独立子目录中:

      app/design/<area>/<Vendor>/<theme>/
      ├── web/
      │ ├── css/
      │ │ ├── source/ 
      │ ├── fonts/
      │ ├── images/
      │ ├── js/
      

      当前你主题的目录结构

      当前,你的主题目录看起来是这样的:

      app/design/frontend/<Vendor>/
      ├── /
      │   ├── etc/
      │   │   ├── view.xml
      │   ├── web/
      │   │   ├── images
      │   │   │   ├── logo.svg
      │   ├── theme.xml
      │   ├── composer.json
      

      主题logo

      在Magento2中,默认的logo名字和格式是logo.svg。当你把一个logo.svg放在常规位置(<theme_dir>/web/images目录)中,它就会被自动识别为主题logo。主题被应用时就会出现在店铺页面的头部。

      在你自定义的主题中,你可以使用不同名字和格式的logo,但是你可能需要声明它。

      是否需要声明取决于你的主题是否有父主题以及它的logo图片。可能是下面的情况:

      • 你的主题没有父主题:
        • 如果你的logo图片名字和格式是默认的,logo.svg,那么就不需要声明它。
        • 如果你的logo图片名字和格式不是默认的就需要声明它。
      • 不的主题有父主题
        • 如果你的主题logo图片名字和格式与父主题的logo一样,那么就不需要声明它。
        • 如果你的logo图片有不同的名字和格式就需要声明它。

      要声明一个主题logo,需要添加一个扩展的<theme_dir>/Magento_Theme/layout/default.xml布局。

      例如,如果你的logo文件是my_logo.png,尺寸为300x300像素,你可以如下声明它:

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
          <body>
              <referenceBlock name="logo">
                  <arguments>
                      <argument name="logo_file" xsi:type="string">images/my_logo.png</argument>
                      <argument name="logo_img_width" xsi:type="number">300</argument> 
                      <argument name="logo_img_height" xsi:type="number">300</argument>
                  </arguments>
              </referenceBlock>
          </body>
      </page>
      

      声明logo尺寸是可选的。更多关于主题的布局,会在之后的文章中详细讲解。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Dec 2015 13:44:16 +0000
      <![CDATA[Magento订单创建和管理]]> https://www.360magento.com/blog/magento_orders/ 如何配置Magento订单选项

      要修改Magento订单选项(结账设置,邮寄设置,支付方式等等)你需要进入后台->System->Configuration。我们要设置的选项在左侧菜单栏的Sales区域。让我们简短地看下这些选项:

      • Sales(销售)-通过这个选项你可以配置支付总额的排序,是否允许再次下单,为PDF和HTML打印输出(发票和装箱单的设计)设置logo,设置最小订单金额和礼物信息。
      • Sales Email(销售电子邮件)-在这里你可以为订单,发票,运输和信用备忘录配置不同的邮箱。更多相关信息你可以在下面的Magento订单邮件部分中到。
      • PDF Print-outs(PDF打印)-这个选项允许你设置是否在发票,装运和信用备忘录的头部显示订单ID。
      • Tax(税)-这里你可以设置不同的税选项-税类,计算设置,税务显示设置和固定产品税。
      • Checkout(结账)-这个重要的选线允许你配置你的结账设置,购物车和侧边栏,支付失败的邮件。
      • Shipping Settings(运输设置)-这里你可以设置你的运输来源和选项。
      • Shipping Method(运输方式)-顾名思义,在这里你可以配置你的运输方式;可用的运输方式有:扁平率,表率,免费送货,UPS,USPS,联邦快递。
      • Google API(谷歌API)-这里你可以为Magento配置谷歌服务-谷歌分析和谷歌结账。
      • Paypal(贝宝)-这个选项允许你为店铺配置贝宝。
      • Payment Method(支付方式)-最重要的选项,这里你应该配置你将接受的支付方式。
      • Payment Services(支付服务)-这里只有一个选项来配置-3D信用卡安全验证 - 这是作为一个额外的安全层,用于网上信用交易的基于XML的协议。
      • Moneybookers -在你的店铺中为Moneybookers配置一个独立的区域。

      如何管理订单邮件

      正如在Magento订单选项中提到的,Magento有一个非常棒的内置的电子邮件功能。这个邮件功能被称作销售电子邮件,允许你管理订单邮件。在配置你的电子邮件之前,你也许需要添加一个新的电子邮件模版。你可以进入后台System -> Transactional Emails来实现。现在,让我们仔细看看每个Sales Email(销售电子邮件)选项:

      • Order and Order Comments(订单和评论)-在这里你可以启用/禁用包含订单和评论信息的客户电子邮件通知。在这里,你可以设置新的订单提交邮件发送者,新的订单确认模版(针对已注册的用户),新的订单确认模版(针对访客用户)。你还可以设置邮件接收订单电子邮件的副本,并选择如何复制邮件发 - 作为密件抄送或作为一个单独的电子邮件。
      • Invoice and Invoice Comments(发票及发票评论)-这里可以启用/禁用包含发票和发票评论的客户电子邮件通知。其他选项与Order相同。
      • Shipment and Shipment Comments (发货和发货评论)-这里可以启用/禁用包含发货和发货评论的客户电子邮件通知。其他选项与Order相同。
      • Credit Memo and Credit Memo Comments(贷项通知单和贷项通知单评论)-这里可以启用/禁用包含贷项通知单和贷项通知单评论的客户电子邮件通知。其他选项与Order相同。

      如何在Magento中下订单

      下订单包含几个简单的步骤。以添加产品到购物车开始,然后进行结账,选择结帐方式,填写一些账单和发货信息,选择付款方式,然后下订单。整个流程表现为:

      Add to Cart -> Process Checkout (Billing/Shipping/Payment) -> Place Order

      一旦订单被下达,它会显示在Magento后台的Sales -> Orders中。

      在Magento中如何管理订单

      当客户成功完成订购过程中,您将收到有关新订单的邮件通知。您可以在后台Sales -> Orders中查看所有的订单。在上一部分中,我们下了订单,让我们点击它,看看它的样子。

      magento Sales Order

      你会在屏幕的右上角发现几个橙色按钮。这些都是你可以对订单进行的操作:

      • Edit(编辑)-该操作会取消当前订单并创建一个有同样细节的订单供你编辑和再次提交。
      • Cancel(取消)-取消订单。
      • Send Email(发送邮件)-重新发送订单电子邮件给客户。
      • Hold(挂起)-将订单挂起,在其它时间进行处理。处理前需(Unhold)恢复。
      • Invoice(发票)-你需要点击(Submit Invoice)提交发票来创建它。这将使得订单状态从待定变为进行中。
      • Credit Memo(贷项通知单)- 只会在发票创建后出现。允许你创建一个线下退款的订单。
      • Ship(发货)-订单管理的最后一步,这是产品的实际交付。你需要点击Submit Shipment(提交发货)来完成订单。它使得订单状态从进行中变为完成。
      • Reorder(再次下单)-允许你再次提交订单。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 16 Dec 2015 14:26:37 +0000
      <![CDATA[Magento产品价格管理]]> https://www.360magento.com/blog/magento_price/ Magento为你的产品价格提供了很多选项。你可以设置特价,定时促销等等。要编辑你的产品价格,首先登录你的Magento后台,然后进入Catalog->Manage Products

      magento manage product

      现在定位你要修改价格的产品上,点击它边上的Edit链接。

      magento product edit

      这里你将看到许多用来修改产品的选项。在左侧菜单选择Prices标签。

      magento product price

      在这里你可以修改产品的价格,下面是一些比较重要选项的说明:

      • Price(价格):你要出售产品的价格,必填项,最重要的信息
      • Cost(成本):你购买产品的价格
      • Tier Price(阶梯价格):可根据购买数量设定折扣
      • Special Price(特价):可设置特价及特价的起止事件,此选项不受购买数量的限制

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 14 Dec 2015 10:50:31 +0000
      <![CDATA[magento社区版本下载]]> https://www.360magento.com/blog/magento-community-download/ 最新最全magento社区版下载链接http://blog.magego.com/magento-download/

      magento 社区版2.x下载列表

      magento 社区版1.x下载列表

      ]]>
      Mon, 30 Nov 2015 08:52:18 +0000
      <![CDATA[magento 2.0发布及介绍]]> https://www.360magento.com/blog/magento-2-launched/ magento官方于2015年11月17日宣布他们的下一代开源电子商务平台magento 2.0正式发布上市。新的平台让品牌商,零售商和企业可以跨越B2C,B2B行业来快速且经济高效的参与全渠道的购物体验。magento 2.0还提供了增强的性能和扩展性,新的功能更能提高转化率和和业务灵活性,以及生产率的提高。magento 2.0还是建立在开源的基础上,并提供无与伦比的灵活性和创新的空间。

      magento基于magento 2.0推出了出了两个版本:magento 2.0企业版 和 magento 2.0社区版,当然还是一样企业版还是每年要收费的。

      开放、灵活的体系结构

      magento 2.0是是下一代平台,全新的架构体系。拥有无与伦比的灵活性,是你的商业眼界和思想能够得以实现。magento 2.0采用模块化的代码库,使自定义更为容易,更快速的推向市场。更强大的部署灵活性使其能够运行在公有云和私有云的环境中。更广泛和更有效的API允许您与任何第三方解决方案连接和操作,主体化的功能使得网站建设随新的产品线或者地域的变化比以往更容易。广泛的turnkey扩展还能够快速、经济的增强你的网店

      吸引人的购物体验

      无论通过任何设备都可以创建一个吸引人的、无缝的和个性化的客户体验是magento 2.0的核心。全新的响应式的参考主题,可以快速的创建一个支持在任何时间、任何地点都可以销售的站点。并且你可以通过集成视频更逼真的方式分享你的产品。全新的结账通过最大限度的减少支付步骤和所需的信息是的更容易定制和进一步提高转化率。您也可以提供一键创建账户来保存未来采购的客户档案。

      增强业务得灵活性和效率

      magento电子商务正在革新商人的体验,使您能够更有效地运作和处理快速增长、不扩大你的团队。新的管理面板的设计提供了一个简化,消费者一样的界面,节省了管理每天的日常任务并且直观的看到新的团队成员学习时的时间。他对触摸屏也是非常有好的,所以无论你去哪儿你都可以更新和跟踪销售订单。改进的业务工具,使您能够不断优化您的操作来推动增长。你现在可以通过后台管理面板轻松的自定义和保存商店视图。创建新的产品也比较快,通过一步步的产品创建向导工具并且产品导入功能比以前快四倍

      企业级可扩展性和性能

      magento平台已经增压,提供更快的超过50%的页面加载时间,在目录页和结账页上有明显体现。以帮助您的客户和提高转换率。它预先集成了 Apache Varnish来缓存页面内容。 Magento企业版2.0还提供了企业级的可扩展性和高可用性与多个从数据库关键子系统独立的主数据库

      安全支付

      此外,magento本身自带的可用PayPal, Braintree, and Authorize.net的支付网关。Magento企业版2.0还集成WorldPay和CyberSource支付网关。所有版本提供更好的安全性和追求PCI合规性的最简单的级别,根据所选择的付款方式

      易于维护和升级

      最后,这个现代化的,模块化的架构降低了复杂性和维护网站的成本。他的升级也很简单,因为他是开源的,这意味着你可以将创新性的功能整合进去。通过magento电商平台来实现每季更高的销售和更高的效率。

       

      下载magento 2.0

      ]]>
      Wed, 18 Nov 2015 11:31:34 +0000
      <![CDATA[Magento创建、修改分类]]> https://www.360magento.com/blog/magento_category/ 如何在Magento中创建分类

      要为产品创建一个分类,你需要进入Magento后台Catalog > Manage Categories。在左侧你将看到已有的分类(如果有的话),在此之上你可以看到两个按钮Add Root Category(添加主分类)和Add Subcategory(添加子分类)。由于我们装了Magento数据,所以有几个分类。让我们通过选择主分类,再通过点击 Add Subcategory来创建新的子分类吧。

      你应该填写它的名字,描述,添加一幅图片,一些有利于搜索引擎优化的Meta数据,设置它为Active来使它显示在前台并且将它包含在导航菜单中。

      最后一个URL关键字,如果设置了就将用来链接到这个分类。这对于SEO来说非常有用,链接中考虑使用一些关键词。如果分类被称为PC,那么你可以考虑在这个区域填上"personal-computers" 。

      magento catalog General Information

      上图是分类的General Information Settings(一般设置),另外还有3个标签你可以设置:

      Display Settings(显示设置):这里你可以设置显示的模式,它的CMS块和产品排列选项。

      Custom Design(自定义设计):这里你可以选择分类的设计,它的布局。

      Category Products(分类产品):这个标签允许你将已有的产品添加到分类中。

      当你设置完成后点击Save按钮来创建它。

      如何在Magento中添加分类图片

      添加Magento分类图片很简单。进入Magento后台Catalog > Manage Categories,选择你要添加图片的分类,选择General Information 标签,点击Image边上的Browse 按钮。选择你要添加的图片,点击Save Category保存。

      magento catalog Image

      如何在Magento中列出所有可用的分类

      如果你想要查看Magento中分类的列表,进入Magento后台Catalog > Manage Categories,在左侧分类菜单中点击Expand All即可。

      magento catalog list

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 14 Nov 2015 16:04:49 +0000
      <![CDATA[Magento2对商家的意味着什么?]]> https://www.360magento.com/blog/magento2-to-merchants/ Magento开发团队已经公布了Magento2 Develop版本,里面包含完整的代码和架构。所有的Magento开发者都能深入了解Magento2了。那么,这对于商家来说意味着什么呢?

      什么是Magento2?

      你肯定知道Magento 1.x。Magento2是对之前的一个重构。大部分的代码已经以一种避免问题的方式重写。特别是,插件冲突,性能,代码质量和当前技术的更新。Magento2承诺满足商家更强大的功能需求。它的变化和提升是建立在过去5年客户的反馈之上的。

      Magento2历程-这一路,它如何走来

      Magento2的发布使得Magento2团队刚刚达到了一座新的里程碑。这意味着架构和代码更加稳定,更多新的功能,稳定性和错误修正。然而商家完全不会受此影响。如今开放的商家测试版大家可以看看,相信2016年你将看到在线网站。

      magento Export Success

      它怎么影响我的Magento店铺?

      Magento将继续支持Magento 1.x产品至2018年并停止对当前版本增加新功能。你的商店也许在2015年不受影响。如果在2015年不升级到magento2,那么在2016或者2017年就要计划了。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 03 Nov 2015 15:59:34 +0000
      <![CDATA[Magento产品数量]]> https://www.360magento.com/blog/magento-quantity/ Magento提供了一种简单又强大的方式来让你管理产品数量。那么我们该如何做呢?首先,登录Magento后台,进入Catalog -> Manage Products

      magento Manage Products

      在下面的页面中,你将看到Magento商店中已有的所有产品。找到你想要修改数量的产品,点击它的Edit链接。

      magento Products Edit

      之后你将进入产品页面,点击左侧菜单中的Inventory

      magento Products Inventory

      现在,定位到Qty区域,加上你想要修改的产品数量。最后点击Save按钮。

      magento Products Qty

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 03 Nov 2015 15:50:37 +0000
      <![CDATA[Magento由Permira基金支持成为独立公司]]> https://www.360magento.com/blog/magento-independent/ The Permira Funds’ Investment in Leading Worldwide Commerce Platform to Fuel Global Expansion and Product Innovation

      CAMPBELL, Calif. — (Nov. 2, 2015) — Magento Commerce, the leading provider of open omnichannel innovation, announced today that it has launched as an independent company, backed by the Permira funds. The launch marks the close of the acquisition of Magento Commerce Technologies by companies owned by the Permira funds from eBay, Inc. Mark Lavelle, formerly senior vice president at eBay Enterprise, will lead the company as its new CEO.

      “Magento is at the forefront of a tremendous market opportunity. As an independent company, with the full support and global resources of the Permira funds, we are poised to accelerate our leadership as innovators, creating products that drive exceptional experiences across every stage of the commerce lifecycle,” said Mark Lavelle, CEO of Magento Commerce. “During our time as a division of eBay, Inc., we grew revenue fivefold, made significant investments in our core platform and added innovative mobile and omnichannel products. Now, we will build on this momentum--continuing to innovate with speed and at scale while we put renewed focus on expanding our market leadership with stronger emphasis on our global network of system integrators, technology partners and developer community.”

      “We are excited to support Mark and his outstanding team as they build on Magento’s product leadership and rich ecosystem,” said Phil Guinand, Principal at Permira. “Given the Permira funds’ experience backing some of the world’s leading brands and retailers, we know first-hand how Magento provides these companies with distinct advantages over their competitors in terms of owning the customer experience, future-proofing their business by leveraging the power of an open architecture, and achieving superior ROI from their omnichannel investments. As the importance of the digital commerce experience expands over the next decade we believe Magento will continue to be the partner of choice for the world’s leading brands and retailers.”

      The flagship open-source Magento platform is already the worldwide leader in eCommerce, powering more than 240,000 sites globally and supporting over $50 billion in gross merchandise volume annually. Magento is the dominant platform to the Internet Retailer Top 1000, and the Internet Retailer B2B 300, counting more than double the number of retailers using the platform to the next closest competitor, as well as to the Internet Retailer Hot 100 which represents retailers who deliver the most innovative and best new ideas in commerce. Additionally, Forrester Research recently cited Magento as a Strong Performer “blending strong strategy with a maturing product" among the eight most significant B2B commerce suite vendors in its industry benchmark report, “The Forrester Wave™: B2B Commerce Suites, Q2 2015.” Magento was also cited as a Challenger in the 2014 Gartner Magic Quadrant for Digital Commerce.

      Emerging as an independent company, Magento Commerce boasts a strong portfolio of open-source and cloud-based omnichannel solutions designed to disrupt the legacy technologies that have siloed the consumer experience between digital and physical:

      • Magento Community Edition is a modular and customizable eCommerce platform that ideally suits the needs of small businesses, and provides core commerce capabilities that can be extended though a wealth of extensions on the Magento Marketplace.
      • The Magento Enterprise Edition is a high performance, scalable eCommerce solution for fast-growing and large businesses. Magento Enterprise Edition provides a rich, robust feature set that can be tailored in order to accelerate business growth across digital and physical channels.
      • Magento Commerce Order Management is a product suite at the core of retail distribution, connecting supply and demand side channels, gathering information from each and facilitating the choices for each individual order. Whether integrated with Magento Enterprise Edition or stand-alone, this modular, cloud-based suite of software, tools, and services, is designed to manage your orders, inventory and fulfillment.
      • Magento Retail Commerce is a product suite designed to provide a more engaging and relevant experience within the retail environment. Magento's Point-of-Service gives store associates a mobile platform to deliver on all of a customer's in store needs, from commerce to clienteling. Magento Retail Commerce blurs the line between online and “offline” in a way the world has never seen before.
      • The Magento Marketplace is the largest commerce application marketplace. The Marketplace provides merchants with a curated user experience for easy discovery of high quality products and services, while providing developers with a vibrant Magento community and the tools and marketing resources to monetize their application business.

      About Magento Commerce

      Trusted by more than 240,000 businesses worldwide, Magento Commerce is the leading provider of open omnichannel innovation to retailers, brands and branded manufacturers across retail B2C and B2B industries. In addition to its flagship open source eCommerce platform, Magento Commerce boasts a strong portfolio of cloud-based omnichannel solutions empowering merchants to successfully integrate digital and physical shopping experiences. With over $50B in gross merchandise volume transacted on the platform annually, Magento Commerce is the dominant provider to the Internet Retailer Top 1000, counting more than double the clients to the next closest competitor, and to the Internet Retailer Hot 100. Magento Commerce is supported by a vast global network of solution and technology partners, a highly active global developer community and the largest eCommerce marketplace for extensions available for download on the Magento Marketplace. More information can be found at www.magento.com.

      About Permira

      Permira is a global investment firm that finds and backs successful businesses with ambition. Founded in 1985, the firm advises funds with a total committed capital of approximately $28 billion. The Permira funds make long-term investments in companies with the objective of transforming their performance and driving sustainable growth. In the past 30 years, the Permira funds have made over 200 private equity investments in five key sectors: Consumer, Financial Services, Healthcare, Industrials and Technology. Permira employs over 200 people in 14 offices across North America, Europe, the Middle East and Asia. For more information visit: www.permira.com.

      Permira established itself in North America in 2002 and today has offices in New York and Menlo Park. The Permira funds have a long track record of successfully investing in technology companies around the world including Informatica, Magento Commerce, eBay Marketing Solutions, NDS, Genesys, Ancestry.com, TeamViewer, Renaissance Learning, Metalogix, LegalZoom.com, and Teraco. Since 1997, over 33% of the Permira funds' investments have been in the core sector of Technology.

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 03 Nov 2015 02:59:12 +0000
      <![CDATA[在不同的商店获取被重写后的产品网址]]> https://www.360magento.com/blog/magento-rewritten-url/ 在之前一篇在不同店铺获取产品网址的文章中,有人指出,如果当你想要获取的产品已经被重写那么将很麻烦。我想到一个返回被重写产品网址的方法。你将需要添加一个店铺的基本网址来返回一个完整网址的值。

      要注意的是:这个方法只有在设置了网址关键字(URL key)属性集范围的店视图(store view)才有效。这意味着一件商品在不同店视图中的网址是不一样的。例如:一个产品在英文店铺中的网址关键字(URL key)是'nokia-blue',在德文店铺中的网址关键字(URL key)是'nokia blau'。这将作用于你正在编辑产品的重写。如果你决定在网址重写中添加一个你自己的网址重写,也许你有一个很好的理由,但是我们不会被这种情况覆盖。

      这次我不会去创建和注册一个模块。让我们以加入这个方法到你的模块助手中开始。

      app/code/community/Alwayly/Rewrites/Helper/Data.php

      <?php
      class Alwayly_Rewrites_Helper_Data extends Mage_Core_Helper_Abstract
      {
          public function rewrittenProductUrl($productId, $categoryId, $storeId)
          {
              $coreUrl = Mage::getModel('core/url_rewrite');
              $idPath = sprintf('product/%d', $productId);
              if ($categoryId) {
                  $idPath = sprintf('%s/%d', $idPath, $categoryId);
              }
              $coreUrl->setStoreId($storeId);
              $coreUrl->loadByIdPath($idPath);
       
              return $coreUrl->getRequestPath();
          }
      }
      ?>
      

      现在我们将做一个小的试演。如你所见,这个方法中接收productId, $categoryId 和 $storeId作为参数。要了解网址(URLS)在被重写前是什么样的,我们一起看下我们数据库中core_url_rewrite的这张表。

      core_url_rewrite表

      一个不在任何类别中产品的id_path表现形式为product/productId,如果它属于任意的类别,它将表现为product/productId/categoryId

      让我们回到我们的方法。我们将用Magento注册表中的数据创建一个id_path的结构体。在我们寻找重写前我们需要为模型用setStoreId()设置店铺的Id。在这之后,我们将用loadByIdPath()读取我们重写了的地址列。现在剩下的就是获取一个请求通道,也就是产品网址中重写的部分。我们将用Magento中的core/url_rewrite模型来实现这些。

      一个例子是,指向你正在寻找的同一产品的语言切换器,但在不同的店视图中。只需将下面的代码放入你的languages.phtml文件。app/design/base/default/template/page/html/switch/languages.phtml

      <?php if(count($this->getStores())>1): ?>
          <?php
          $helper = Mage::helper('inchoo_rewrites');
          $prod = Mage::registry('current_product');
          $categ = Mage::registry('current_category');
          $categId = $categ ? $categ->getId() : null;
       
          ?>
          <div class="form-language">
              <label for="select-language"><?php echo $this->__('Your Language:') ?></label>
              <select id="select-language" title="<?php echo $this->__('Your Language') ?>" onchange="window.location.href=this.value">
                  <?php foreach ($this->getStores() as $_lang): ?>
                      <?php $_selected = ($_lang->getId() == $this->getCurrentStoreId()) ? ' selected="selected"' : '' ?>
                      <option value="<?php
                          if($prod) {
                              echo $_lang->getBaseUrl() . $helper->rewrittenProductUrl($prod->getId(), $categId, $_lang->getId()) . '?___store=' . $_lang->getCode();
                          }else{
                              echo $_lang->getCurrentUrl(false);
                          }
                      ?>"<?php echo $_selected ?>><?php echo $this->escapeHtml($_lang->getName()) ?></option>
                  <?php endforeach; ?>
              </select>
          </div>
      <?php endif; ?>
      

      你的语言切换器源码应该有些像这样(只要你的产品至少在一个店铺中有不同的网址)

      language switcher

      希望这将对你们掌握多店铺中网址重写的概念有所帮助。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 02 Nov 2015 15:38:20 +0000
      <![CDATA[在Magento中导入产品]]> https://www.360magento.com/blog/magento-import-products/ 在Magento中以手动的方式添加大量产品是很不方便的。一件一件地添加产品会消耗很长的时间,特别是当你有成百上千的产品。这种情况,你就需要一种自动的方式添加所有的产品到你的Magento店铺。按照下面的步骤就能成功导入。

      首先,从Magento后台进入Catalog -> Manage Categories

      magento Manage Categories

      填写如下的内容来创建所有你需要的分类:

      magento Categories Information

      填写所有的信息以后,点击Save Catagory按钮。

      magento Save Catagory

      注意,记下新创建的分类的id。最好以文本的形式,如下:

      magento Catagory id

      如果需要,你还可以通过Catalog ->Attributes ->Manage Attributes -> Add new Attribute.创建产品的额外属性。当然,在创建简单产品的时候你也可以创建属性。什么时候创建由你决定。

      下一步是在Magento中手动添加一个产品。之后用来导出作为大量数据导入的模版。确保已经创建了所有需要的属性,是否删除已有的商品。当你创建并保存一个新产品以后,它将出现在Magento店铺的产品列表里。

      magento product list

      现在导出作为样本的模版。在Magento后台System -> Import/Export -> Dataflow - Profiles -> Export All Products。在Profile Information -> Store选择你刚才创建产品所在的店铺。在Data Transfer下拉菜单选择Local/Remote Server。在Data Format这栏选择CSV/ Tab Separated,点击Save按钮。接着再次点击export all products,点击Run Profile in Popup按钮。

      在你的项目的var/export/文件夹里将有一个名为export_all_products.csv的文件。导出成功的界面看起来是这样的:

      magento Export Success

      使用FTP将文件下载到本地。文件里每一列对应你要定义产品的属性。用电子表格程序打开它,添加你要导入的产品。确保复制/粘贴属性到对应的列。记得添加上分类的id。

      完成这些之后,返回Magento后台,进入System -> Import/Export -> Dataflow - Profiles -> Import All Products。之后选择Upload,上传要导入的.csv文件。上传完以后再次点击Import All Products,之后Run Profile,从下拉框选择你刚才上传的文件,点击Run Profile in Popup按钮。一个导入状态的窗口就弹出了。

      magento Import process

      导入成功后会有提示信息。

      magento Import Success

      现在,你可以到后台产品页面查看导入的产品了。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 02 Nov 2015 13:08:23 +0000
      <![CDATA[更新购物车中的可配置产品]]> https://www.360magento.com/blog/updating-cart-configurable/ 假设我们的购物车中有Magento可配置产品,我们想要修改它的选项但又不愿意删除或者重新添加它,那么怎么办呢?其实,按照下面的步骤,实现起来还是很简单的。

      首先,打开你主题文件夹下的template/checkout/cart/item/default.phtml,找到下面的代码:

      <?php if ($_options = $this->getOptionList()):?>
      

      在这行代码下面添加:

      < ?php
      if($this->getProduct()->isConfigurable()){
      $_product = Mage::getModel('catalog/product')->load($this->getProduct()->getId());
      Mage::getBlockSingleton('catalog/product_view_type_configurable')->unsetData();
      $_configurable = Mage::getBlockSingleton('catalog/product_view_type_configurable')->setData('product', $_product);
      $_cdata = json_decode($_configurable->getJsonConfig());
      $_current = array();
      foreach((array)$this->getOptionList() as $_option) {
      $_current[$_option['label']]=$_option['value'];
      }
      foreach($_cdata->attributes as $attribute) {
      ?>
      <strong>< ?php echo $attribute->label; ?></strong>
      <select style="width:150px;" name="cart[<?php echo $_item->getId() ?>][option][< ?php echo $attribute->id ?>]">
      < ?php
      foreach($attribute->options as $option) {
      ?>
      <option <?php echo ($_current[$attribute->label]==$option->label) ? ' selected' : '' ?> value="< ?php echo $option->id ?>">< ?php echo $option->label ?> < ?php echo $this->helper('checkout')->formatPrice($option->price+$_item->getProduct()->getPrice()) ?></option>
      < ?php
      }
      ?>
      </select>
      < ?php
      }
      } else {
      // THIS IS PLACE WHERE EXISTING CODE from [*] goes
      }
      ?>

      现在你已经完成了模板,你可以以你喜欢的方式来装饰它。下一步,你需要在local下创建你的“Model”和“etc”。etc中的config.xml代码是:

      < ?xml version="1.0"?>
      <config>
      <frontend>
      <events>
      <checkout_cart_update_items_before>
      <observers>
      <your_firm_module_name_event>
      <type>singleton</type>
      <class>YOUR_FIRM_MODULE_NAME_Model_Card</class>
      <method>update</method>
      </your_firm_module_name_event>
      </observers>
      </checkout_cart_update_items_before>
      </events>
      </frontend>
      </config>
      

      “Model”中的Card.php代码为:

      < ?php
       
      class YOUR_FIRM_MODULE_NAME_Model_Card
      {
      public function update($e)
      {
      $_this = $e->cart;
      $data = $e->info;
       
      foreach ($data as $itemId => $itemInfo) {
      $item = $_this->getQuote()->getItemById($itemId);
       
      if (!$item) continue;
      if (!isset($itemInfo['option']) or empty($itemInfo['option'])) continue;
       
      foreach ($item->getOptions() as $option){
       
      if($option->getCode()=='info_buyRequest'){
       
      $unserialized = unserialize($option->getValue());
      $unserialized['super_attribute'] = $itemInfo['option'];
      $option->setValue(serialize($itemInfo['option']));
       
      }elseif ($option->getCode()=='attributes'){
      $option->setValue(serialize($itemInfo['option']));
      }
       
      }
      $item->save();
      }
      }
       
      }
      ?>
      

      最后在app/etc中用下面的代码创建YOUR_FIRM_MODULE_NAME.xml。

      < ?xml version="1.0"?>
      <config>
      <modules>
      <your_firm_module_name>
      <codepool>local</codepool>
      <active>true</active>
      </your_firm_module_name>
      </modules>
      </config>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 01 Nov 2015 11:16:40 +0000
      <![CDATA[Magento 创建、修改CMS]]> https://www.360magento.com/blog/magento_home_design/ 为了管理网站页面,你需要进入后台CMS区域。点击Pages链接进入页面修改。

      magento CMS

      通过点击页面,你就可以修改它。修改页面将展开下面这样的窗口:

      magento Page

      你可以按你的喜好来进行修改。Static block是另一种非常有用的选项。例如,你可以编辑页面底部包含链接的footer块:

      magento Static Block

      Polls区域允许你创建和修改投票:

      magento Poll

      事实上,Magento集成了一个功能齐全的CMS系统。你可以添加不同的元素到你的网站里。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 01 Nov 2015 11:10:26 +0000
      <![CDATA[如何在Magento2中创建主题(第二部分)]]> https://www.360magento.com/blog/magento2-theme-2/ 2.配置和创建主题文件夹

      ·按app/design/<area>/<vendorName>/<newTheme>/的结构在design文件夹下创建主题文件夹

      例如:/app/design/frontend/Magento/magestore

      声明主题

      在刚创建的magestore主题文件夹里创建theme.xml文件。声明信息包括:主题,版本,父类主题(如果是继承主题)

      <theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Config/etc/theme.xsd">
      <title>Alwaylystore Theme</title>
      <media>
      <preview_image>media/preview.jpg</preview_image>
      </media>
      </theme>
      

      为新主题创建一张图片:magestore.png,它的文件位置是:/app/design/frontend/Magento/magestore/media/theme/preview/magestore.png。如果路径不对会找不到图片的。

      在主题文件夹里创建composer.json文件

      {
          "name": "magento/theme-frontend-blank",
          "description": "N/A",
          "require": {
              "php": "~5.4.11|~5.5.0",
              "magento/framework": "0.42.0-beta1",
              "magento/magento-composer-installer": "*"
          },
          "type": "magento2-theme",
          "version": "0.42.0-beta1",
          "license": [
              "OSL-3.0",
              "AFL-3.0"
          ],
          "extra": {
              "map": [
                  [
                      "*",
                      "frontend/Magento/blank"
                  ]
              ]
          }
      }
      

      在后台,进入 Content > Design > Themes,可以看到新主题;

      magento2新主题

      配置图片(可选)

      在view.xml中,图片的尺寸将被配置。在新主题中新的文件夹被创建在 app/design/<area>/<vendorName>/<newTheme>/etc/

      例如: /app/design/frontend/Magento/magestore/etc/

      把默认主题中的view.xml文件拷贝到<etc>文件夹中

      magento2etc

      在view.xml中配置前端显示设置。例如,设置图片的尺寸到120px

      <var name="new_products_content_widget_grid:type">small_image</var>
      <var name="new_products_content_widget_grid:width">120</var>
      <var name="new_products_content_widget_grid:ratio">1</var>
      <var name="new_products_content_widget_grid:height">120</var>
      

      创建图片文件夹

      在主题中,创建<web>文件夹,并在<web>文件夹内创建<image>文件夹:

      App/design/<area>/<vendorName>/<newTheme>web/images/

      例如: /app/design/frontend/Magento/alwaylystore/web/images/

      为主题添加一个logo图片

      进入app/design/<area>/<vendorName>/<newTheme>web/images/

      例如:/app/design/frontend/Magento/mageystore/web/images/

      拷贝名为logo.png的图片到文件夹中。 Magento默认设置logo.gif图片作为logo图片。如果你想要修改,那么拷贝默认主题里的/Magento_Theme/layout/default.xml到你的主题中。

      例如:/app/design/frontend/Magento/magestore/Magento_Theme/layout/default.xml

      添加下面的代码:

      <referenceBlock name="logo">
      <arguments>
      <argument name="logo_file" xsi:type="string">images/logo.png</argument>
      </arguments>
      </referenceBlock>
      

      现在,我们的文件结构看起来像是这样的:

      magento2 default.xml

      使用创建的主题:

      进入后台Store > Configuration > Design在Design Theme里选择我们创建的主题,然后保存。

      magento2使用新主题

      我们已经创建了一个新主题的文件结构,下面的部分将一步一步地配置你的主题。

      3.基础元素定制

      定制CSS:

      /app/design/frontend/Magento/blank文件夹中拷贝web/css文件夹

      magento2 web/css

      粘贴到你的主题相应的文件夹中(/app/design/frontend/Magento/magestore/web):

      magento2 new web

      到文件夹/lib/web/css/source/lib中拷贝lib.css文件到Magestore主题中

      magento2 lib.css

      打开app/design/frontend/Magento/magestore/web/css/中的style.less文件,如下编辑代码:

      magento2 style.less

      之后,在你的source文件夹里创建mytheme.less。

      我们就有了这样的文件路径:app/design/frontend/Magento/magestore/web/css/source/mytheme.less,将下面的代码加入到mytheme.less中:

      body {
        margin: 0px!important;
        padding: 0px!important;
      }
       
      .page-wrapper {
        background-color: #333;
      }
       
       
      .mycustom-class {
        color: red;
      }
      

      删除Var/cache文件夹,刷新你的浏览器,你将看到:

      magento2 mytheme修改效果

      定制模版模块:

      你还可以定制任何模块的html,例如,如果你想定制前端的Magento_Catalog模块,到模块的app/code/Magento/Catalog/view/frontend/文件夹中,拷贝layout, templages, web文件到你的主题中并放置到和模块一样名字的Magento_catalog文件夹中,例如:

      magento2 Magento_Catalog

      让我们把“Buy this product now”加入到“Add to Cart”之下。

      magento2 添加语句到Add to cart下效果

      进入app/design/frontend/Magento/magestore/Magento_Catalog/templates/product/view/addto.phtml文件,在第31行的位置,如下编辑:

      magento2 添加语句到Add to cart下代码

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 31 Oct 2015 14:25:59 +0000
      <![CDATA[Magento邮寄方式的设置和修改]]> https://www.360magento.com/blog/magento_shipping_methods/ 要配置你的Magento邮寄方式,你需要登录后台,然后进入System -> Configuration -> Sales ->Shipping Methods.

      magento Shipping Methods

      在开启邮寄方式前你需要完成邮寄方式的设置,在System -> Configuration -> Sales -> Shipping Settings.

      magento Shipping Setting

      展开Origin区域。输入产品的发货地址,通常是产品存储的仓库。之后展开Option区域。开启Allow Shipping to Multiple Addresses就允许一个订单中的货物发送到多个地址。这是很实用的,比如一个客户买了很多明信片或者钢笔之类的东西,他想要发给不同的地址。你可以在Maximum Qty Allowed for Shipping to Multiple Addresses这一栏定义允许邮寄的地址的最大数量。

      例如,要开启USPS邮寄方式,你可以进入System -> Configuration -> Sales -> Shipping Methods,转到USPS区域:

      magento Shipping USPS

      开启邮寄方式,输入Gateway URL和UserID。下面的选项允许你描述包裹的信息(大小,重量等等……)。然后你可以定义handling fee(手续费),可以是固定值也可以按百分比计算。之后你可以选择运输方式,你也可以配置一个到多少金额免运费的方法。

      最后,你可以定义支持运输的国家和运输服务出错时的报错信息。在Sort order选项你应该输入这个运输方法相对其它运输方法的位置。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 31 Oct 2015 14:25:00 +0000
      <![CDATA[Magento支付方法的设置和修改]]> https://www.360magento.com/blog/magento_payment_methods/ Magento提供不同的支付方法来支持各种支付方式。例如:Paypal,Authorize.net和其它的支付方式。客户也能通过普通信用卡(如Visa,Master Card,American Express等……)来完成支付。

      要在Magento中配置你的支付方式,你需要先进入后台,接着System -> Configuration -> Sales -> Payment Methods

      magento Payment Methods

      在这篇教程里,我们将开启信用卡支付方法。这个方法可以在Saved CC区域配置:

      magento Saved CC

      开启方法,输入标题,设置新的订单状态,挑选支持的信用卡,决定是否需要信用卡验证,通过设置允许支付的国家来限定支付的范围。

      填写Sort order可调整与其它支付方式的相对位置。好了,你已经为客户开启了这种支付方法。由于所有的支付方法都有不同的配置,我没办法在这里逐个详细说明,只要按照特定页面的说明,它们就应该可以工作。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 30 Oct 2015 12:37:12 +0000
      <![CDATA[如何在Magento2中创建主题(第一部分)]]> https://www.360magento.com/blog/magento2-theme-1/ 嘿,伙计。你已经积累多少Magento2知识了,有没有想要和大家分享的?我在Magento2中发现了一些有趣的功能。不论你是插件或主题开发人员,你都应该花时间读读这篇文章。因为你将明白更多关于Magento2主题和模版结构的知识。

      我把这个教程分成了两个部分。今天的这篇是第一部分,关于主题包中的基础元素。第二部分将展示如何在Magento2中自定义它。

      1、主题包中的基础元素

      a.Magento2中的主题结构

      Magento2的MVC结构比Magento1中更加明了。Magento2模块将添加View元素到模块文件结构里。以Catalog为例:app/code/Magento/Catalog/

      magento Catalog

      注意,View元素和Controller,Model在同一位置。展开View文件夹,你将看到:

      magento Catalog View

      你可以看到,这个结构下有3个元素,他们是从 标签移出来的。 文件结构展开以后包含layout, templates, web。例如,frontend有3个基础文件夹:

      magento Catalog View frontend web

      Layout(布局)文件夹包含所有模块的布局文件(类似于Magento 1.x,布局文件包含在主题文件夹的Layout里)。当然,这些布局的代码有不同的结构。我将在后面具体的部分说明。

      Template(模板)文件夹有所有的.phtml文件,和Magento1中一样由php和html代码混合而成,用来渲染成html。

      Web文件夹是Magento2中新出现的文件夹,你可以从下图看到它的组成:

      web文件夹结构

      不难看出,它里面包含了CSS,JS和Images文件夹。也就是说,在Magento2中,旧的skin文件夹被划分到每个模块中去了,使得模块更加独立。

      b.Layout

      在Magento2中,每个模块有默认的布局,可以被重写或被另一个布局扩展。

      例如:app/code/Magento/Catalog/view/frontend/layout/default.xml

      Magento用特别的句柄来分离布局文件。

      layout

      句柄的声明和之前规则一样catalog_product_view是一个根据模块和控制器动作命名的句柄。定义页面则需要更加具体的声明:catalog_product_view_type_simple_id_128。或者我们可以调用其它句柄。这里是关于Catalog模块布局文件位置的示例:

      Magento2 Catalog模块布局文件

      模块中有两种布局,Base layoutTheme layout

      Base layout是每个模块默认的布局区域。如果不是你自定义的模块,我们是不建议你直接修改这些文件的。

      例如:app/design/frontend/Magento/blank/Magento_Checkout/layout/

      __app/code/<Namespace>/<Module>|__/view|__/<area>|__/layout|–<layout_file1>.xml|–<layout_file2>.xml

      Theme layouts是模块的外部主题,允许通过报告主题文件中对应的<Namespace>_<lModule>来定制默认的主题布局。

      例如:app/design/frontend/Magento/blank/Magento_Checkout/layout/

      Magento2 Checkout布局

      创建一个布局文件要遵循下面的规则:

      • 每个布局文件调用一个句柄,其它被调用;
      • 布局文件的名字就是布局句柄的名字,例如:checkout_cart_index
      • 布局文件在布局文件夹中被调用

      例如:

      <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <update handle="page_one_column" />
         <referenceContainer name="content">
         <!-- ... -->
         </referenceContainer>
      </layout>
      

      下面描述布局文件的读取和处理顺序

      • 如果布局文件属于不同的模块,那么执行的顺序将是:独立模块,相关模块,然后按字母顺序排列;
      • 如果文件属于同一个模块,那么就按文件名字的字母顺序排列。

      布局系统执行的步骤

      • 读取所有默认布局文件组(base),包括关联的那个;
      • 决定继承和重写文件的顺序;
      • 添加所有被展开的布局,替换掉base中的布局,获取父类布局,替换被子类重写的父类布局。

      下面是布局进程的模型:

      Magento2布局进程

      由此看以看出,布局文件是由上自下被重写的,父类主题重写模块中的base主题,子主题(一般是我们定义的主题)重写父类。例如:Module_One模块的布局文件layout_2在重写文件夹中的父类主题parent_theme里被声明。因此,系统会用parent_theme > Module_One > override > layout_2.xml替换掉Module_One > layout_2.xml。

      布局/块区域:

      和magento1一样,它分为基础的布局区域:

      Container(容器):分配页面元素的区域

      Magento2容器

      Block(块):容器中默认Magento块元素所在的区域

      Magento2块

      下面是一个布局内容示例:

      <container name="container.1" label="Container 1"
      as="container_1" output="1" htmlTag="div" htmlId="container-1"
      htmlClass="container">
      <block class="Magento\Module\Block\Class" name="block.1">
      <container name="child.container" label="Child Container" as="child">
      <block type="Magento\Module\Block\Class" name="block.2">
      </container>
      <block class="Magento\Module\Block\Class" name="block.3"/>
      </container>
      <container name="container.2" as="container_2" htmlTag="div"
      htmlId="container-2" htmlClass="container"/>
      

      c.新语言风格LESS介绍

      在定义主题元素之前,我们需要学习新的语言风格-LESS。在Magento2中这个语言很有趣。由于有一些高级的功能,LESS的添加级别要高于CSS。它被翻译成CSS得益于php中的LESS库。我们仍然允许在源码中添加CSS URL直接使用。

      LESS语言的预处理是通过lib/internal/Magento/Css/PreProcesso中的库完成的。在LESS文件中的导入方式是:

      file.less

      @magento_import “<some_id>”;
      @import “path/to/dir1/some_file”;@import “path/to/file/file1.less”;@import “path/to/file/file2.less”;
      

      想要了解更多关于LESS语言,你可以访问http://lesscss.org/或者http://less.eten.vn/

      默认的LESS库文件结构是:

      lib/web/ ├── css/

      │ ├── docs/ (Library documentation)

      │ ├── source/

      │ │ ├── lib/ (Library source files)

      │ │ │ ├── abstract.less

      │ │ │ ├── actions-toolbar.less

      │ │ │ ├── breadcrumbs.less

      │ │ │ ├── buttons.less

      │ │ │ ├── dropdowns.less

      │ │ │ ├── forms.less

      │ │ │ ├── icons.less

      │ │ │ ├── layout.less

      │ │ │ ├── lib.less

      │ │ │ ├── loaders.less

      │ │ │ ├── messages.less

      │ │ │ ├── navigation.less

      │ │ │ ├── pages.less

      │ │ │ ├── popups.less

      │ │ │ ├── rating.less

      │ │ │ ├── resets.less

      │ │ │ ├── responsive.less

      │ │ │ ├── sections.less

      │ │ │ ├── tables.less

      │ │ │ ├── tooltips.less

      │ │ │ ├── typography.less

      │ │ │ ├── utilities.less

      │ │ │ └── variables.less

      │ │ └── theme.less

      │ └── styles.less

      ├── fonts/

      │ └── Blank-Theme-Icons/ (Library custom icons font)

      ├── images/

      │ └── blank-theme-icons.png (Library icons sprite)

      └── jquery/ (Library javascript files)

       

      d.Mage_page元素

      之前Magento版本中的Mage_page元素被Mangento_Theme模块替代了。

      现在,准备好学习下一章了吗?那么开始第二部分吧!

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 30 Oct 2015 12:24:27 +0000
      <![CDATA[Magento产品教程]]> https://www.360magento.com/blog/magento_product/ 在这篇教程中我们将讨论网店中最重要的一个方面--你的产品。一旦你读了这篇教程,你将知道如何添加、管理产品,给产品添加图片和标签。

      1、在Magento中如何添加产品

      进入Magento后台-> Catalog -> Manage Products -> Add Product

      magento产品添加

      选择产品设置(属性组和产品类型),点击Continue按钮;

      magento产品属性组和类型选择

      在接下来的页面里,你需要填写产品的相关信息(Name, SKU (Stock Keeping Unit), Weight, Status (Enabled/Disabled), Tax Class等等……)你也可以通过Create New Attribute按钮为产品添加自定义属性。

      magento产品基本信息

      填好以后,点击Save and Continue Edit按钮,在下一个选项卡里你将为产品定价。你也可以添加像Tier Price和Special Price这样的特殊价格。

      magento产品价格

      点击Save and Continue Edit按钮保存产品,如果想让产品在前端显示,请务必设置Inventory为In Stock。

      2、如何为产品添加图片

      在Magento中为产品添加图片是很容易的。在后台-> Catalog -> Manage Products出现的网格中选择你要添加图片的产品,然后在左侧选择Images选项。点击Browse Files按钮,然后选中你要上传的图片,再点击Upload Files上传图片到服务器。最后,选择用点选按钮选择图片出现的位置,点击Save按钮。

      magento图片上传

      3、如何管理产品属性

      点击Create New Attribute按钮可为产品创建属性

      magento添加属性

      属性填写完以后点击Save Attribute按钮,在category选项卡里可为产品选择一个分类。最后点击Save按钮保存产品信息。

      magento产品加入分类

      4、如何管理产品标签

      默认地,Magento允许顾客对产品进行标记。当客户给某个产品标记以后,标签会变为待定状态,只有被批准以后才会显示在产品页面。

      让我们给产品添加标签,批准它,然后看它在产品详细页是如何显示的。添加产品标签只需要简单地在Add Your Tags区域填写、提交即可。我们添加"Great"标签,点击Add Tags,之后会出现一条提示信息,说明标签已经被接收。

      magento标签添加

      接着,进入后台-> Catalog -> Tags -> Pending Tags,这里可以看到所有的标签。在我们这种情况下,只有一个出于"Pending"状态下名为"Great"的标签。

      magento标签列表

      点击它,你就会看到下面的界面,在这里将"pending"改为"Approved",点击Save Tag。

      magento标签状态修改

      现在,这个标签就被批准了,其它客户可以在对应产品的详细页看到这个标签了。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 29 Oct 2015 15:57:55 +0000
      <![CDATA[如何在Magento2中创建一个简单的模块]]> https://www.360magento.com/blog/create-magento2-module/ 本示例中命名空间为:Magento,模块名为:Hello,示例链接为http://localhost/magento20/hello/index/index。

      1、创建app/code/Magento/Hello/etc/module.xml文件来声明模块

      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
         <module name="Magento_Hello" schema_version="0.0.1"/>
      </config>
      

      2、创建控制器和动作:

      创建app/code/Magento/Hello/Controller/Index/Index.php,其中Index扮演控制器的角色,Index.php是动作。Index.php中执行的方法是execute()。

      namespace Magento\Hello\Controller\Index;
      class Index extends \Magento\Framework\App\Action\Action
      {
        public function execute()
      {
           $this->_view->loadLayout();
             $this->_view->getLayout()->initMessages();
          $this->_view->renderLayout();
      }
      }
      

      创建一个块:app/code/Magento/Hello/Block/Hello.php

      namespace Magento\Hello\Block;
      class Hello extends \Magento\Framework\View\Element\Template
      {
      public function _prepareLayout()
      {
          return parent::_prepareLayout();
      }
      }
      

      写配置文件/app/code/Magento/Hello/etc/frontend/routes.xml

      在Magento2中config.xml 只配置默认<default>标签中的配置值。前端路由的信息会在Magento/Hello/etc/frontend/routes.xml中(后台也是类似的)。前端事件会被声明在Magento/Hello/ect/frontend/events.xml(后台类似)。我们这里只是一个简单的示例,只在Magento/Hello/etc/frontend/routes.xml中声明路由。

      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
      <router id="standard">
          <route id="hello" frontName="hello">
              <module name="Magento_Hello" />
          </route>
      </router>
      </config>

      3、创建前端模板

      这一步中布局的名字很重要,它将被命名在结构后:router name_controller namer_action name(路由器名_控制器名_动作名)。

      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
      <body>
          <referenceContainer name="content">
              <block class="Magento\Hello\Block\Hello" name="hello" template="success.phtml">
              </block>
          </referenceContainer>
      </body>
      </page>
      

      接着,我们创建布局文件中调用的success.phtml文件。

      <?php echo ‘Successful! This is a simple module in Magento 2.0′; ?>
      

      4、打开app/etc/config.xml,在‘module’数组里添加元素‘Magento_Hello’ => 1,

      最后访问http://localhost/magento20/hello/index/index,查看结果。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 28 Oct 2015 12:27:38 +0000
      <![CDATA[Magento的安装]]> https://www.360magento.com/blog/magento-installation/ 1.从官网下载最新的Magento安装包:http://www.magentocommerce.com/download

      2.将下载的安装包放到安装环境下,本地使用wamp或者xamp,在线则需要使用cPanel或者FTP工具;

      3.本地进入phpmyadmin(线上则用cPanel的MySQL管理),创建一个数据库和用户,在安装过程中会用到。

      4.在浏览器中输入Magento安装包地址就会进入安装步骤,会看到如下界面:

      magento安装协议

      勾选"I agree to the above terms and conditions",点击Continue按钮;

      magento安装语言环境

      选择时区和货币类型,点击Continue按钮;

      magento安装数据库配置

      进入数据库安装页面,输入之前创建的数据库名和用户名,密码,勾选"Skip Base URL validation before next step"选项,点击Continue按钮;

      magento安装个人设置

      最后进入个人信息和后台登录详情页面,按要求填写信息,点击Continue按钮即可。

      magento安装数据库成功

      安装成功,可点击对应的按钮进入前端或者后台。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 28 Oct 2015 12:13:51 +0000
      <![CDATA[ 如何重写Magento模型类?]]> https://www.360magento.com/blog/override_magento_model/ 很多时候当我想要实现新功能,但又不想修改核心类。对于控制器来说,这很简单。从核心文件中拷贝控制器,放到local中同样的位置,然后修改就可以了。但这不适用于模型,那么如何在不修改核心文件的前提下重写Magento模型呢?

      幸运的是,这并不难。让我们一起做个插件吧。我们以app/code/core/Mage/Wishlist/Model/Item.php中的Mage_Wishlist_Model_Item为例。我们想要添加新的功能,所以创建新的模块。app/code/local/Alwayly/Wishlist/Model/Item.php。现在将Mage_Wishlist_Model_Item重命名为Alwayly_Wishlist_Model_Item并在loadByProductWishlist方法加入下面一行代码:

      var_dump(get_class($this)); exit();
      

      现在,在app/etc/modules/中创建Alwayly_Wishlist.xml,代码如下:

      < ?xml version="1.0"?>  
      <config>  
          <modules>  
              <alwayly_wishlist>  
                  <active>true</active>  
                  <codepool>local</codepool>  
              </alwayly_wishlist>  
          </modules>  
      </config> 
      

      接着用下面的代码创建app/code/local/Alwayly/Wishlist/etc/Config.xml

      < ?xml version="1.0"?>
      <config>
          <modules>
              <alwayly_wishlist>
                  <version>0.1</version>
              </alwayly_wishlist>
          </modules>
          <global>
             <models>
                <wishlist>
                    <rewrite>
                        <item>Alwayly_Wishlist_Model_Item</item>
                    </rewrite>
                </wishlist>
             </models>
          </global>
      </config>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 27 Oct 2015 12:19:24 +0000
      <![CDATA[以编程的方式创建Magento并与布局关联]]> https://www.360magento.com/blog/programatically-blocks-layout/ 想像一下,当你要创建一个简单的视图文件(例如,custom-note.phtml)并在Magento的一些新链接中展示出来。一种方式是创建CMS页面,在CMS页面中调用这个块。但是当你想要让这个块在Magento布局的其它部分,或者说后台CMS修改不了的地方?如果我想在面包屑导航下面添加新的div元素或者新的块,又该如何做?

      Magento的理念是在你模块的/Block文件夹下创建块类,/layout文件夹下创建xml布局文件,等等。总之,你要么需要创建Block文件或添加/修改布局文件入口。

      一切都确定好了,如果你要在多店铺中开发一个模块,我首要关心的就是将必要模块文件的数量降到最低。下面的代码将让你知道调用Core/Template块到任何Magento布局区域是多么简单。

      app/code/local/ActiveCodeline/CustomOutputs/controllers/IndexController.php

      public function indexAction()
      {
      //Get current layout state
      $this->loadLayout();
       
      $block = $this->getLayout()->createBlock(
      'Mage_Core_Block_Template',
      'my_block_name_here',
      array('template' => 'activecodeline/developer.phtml')
      );
       
      $this->getLayout()->getBlock('content')->append($block);
       
      //Release layout stream... lol... sounds fancy
      $this->renderLayout();
      }
      

      值得注意的是,当你提交一个无效的块到->append()时,可能什么也不会发生。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 27 Oct 2015 12:14:20 +0000
      <![CDATA[Magento自定义邮件]]> https://www.360magento.com/blog/magento-custom-emails/ 是否曾想过用Magento内置的电子邮件功能发送邮件?是否想在Magento中做些什么的时候碰壁?好吧,我已经知道答案了。总之,Magento发送邮件被证实只要几个小时跟踪Magento代码。那么,我要创建名为activecodeline_custom_email1.html电子邮件,我想在它运行时传几个变量给它,我要以编程的方式发送电子邮件。

      下面就是:

      ...
      /*
       * Loads the html file named 'custom_email_template1.html' from
       * app/locale/en_US/template/email/activecodeline_custom_email1.html
       */ 
      $emailTemplate  = Mage::getModel('core/email_template')
      						->loadDefault('custom_email_template1');					
      
      //Create an array of variables to assign to template
      $emailTemplateVariables = array();
      $emailTemplateVariables['myvar1'] = 'Branko';
      $emailTemplateVariables['myvar2'] = 'Ajzele';
      $emailTemplateVariables['myvar3'] = 'ActiveCodeline';
       
      /**
       * The best part :)
       * Opens the activecodeline_custom_email1.html, throws in the variable array 
       * and returns the 'parsed' content that you can use as body of email
       */
      $processedTemplate = $emailTemplate->getProcessedTemplate($emailTemplateVariables);
       
      /*
       * Or you can send the email directly, 
       * note getProcessedTemplate is called inside send()
       */
      $emailTemplate->send('john@someemail.com','John Doe', $emailTemplateVariables);
      ...
      

      为了让上面的代码工作,你需要在config.xml中添加下面的代码:

      ...
      <global>      
      	<template>
      		<email>
      			<custom_email_template1 module="SampleModule1">
      				<label>ActiveCodeline custom email module</label>
      				<file>activecodeline_custom_email1.html</file>
      				<type>html</type>
      			</custom_email_template1>
      		</email>
      	</template>
      </global>  
      ...
      

      不要忘了邮件模版app/locale/en_US/template/email/activecodeline_custom_email1.html.

      <!--@subject ActiveCodeline custom email module @-->
       
      <div>
      <h1>ActiveCodeline custom email example by Branko Ajzele</h1>
      <p>Hi there {{var myvar1}} {{var myvar2}} from {{var myvar3}}. This is just some example template to test custom email module.</p>
      </div>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 26 Oct 2015 12:57:05 +0000
      <![CDATA[如何用前端模版代码删除Magento产品]]> https://www.360magento.com/blog/delete-magento-product/ 由于某些原因,你可能需要在视图文件中用自定义代码删除产品。但是你会惊讶的看到 “Cannot complete this operation from non-admin area.”这样的报错。下面有些小技巧让你实现它。

      这里是奏效的代码部分:

      $_authors_product = new Mage_Catalog_Model_Product();
      	$_authors_product->load($_item_val_id);
       
      	//echo "DELETED... ".$_POST['submit_item4sale_remove_by_entity_id'];
      	$_item_val_id = $_POST['submit_item4sale_remove_by_entity_id']; 
      	$_item_val_id = (int)str_replace('entity_id_', '', $_item_val_id);
       
      	$_authors_product = new Mage_Catalog_Model_Product();
      	$_authors_product->load($_item_val_id);
       
      	$_current_customer_id = Mage::getSingleton('customer/session')->getCustomer()->getId();
       
      	//Allow deletion only if product is from author
      	if($_authors_product->submited_by_author == $_current_customer_id) 
      	{
      		//var_dump(Mage::registry('isSecureArea'));
       
      		Mage::register('isSecureArea', true);
      		//$_authors_product->delete();
      		echo 'ALLOWED DELETED OH YEAAAAAA....';
      		Mage::unregister('isSecureArea');	
      	}
      

      上面的代码是我最近项目中的一部分,其中最重要的是:

      Mage::register('isSecureArea', true);
      echo 'ALLOWED DELETED OH YEAAAAAA....';
      Mage::unregister('isSecureArea');
      

      基本的想法是在注册表中写入合适的值Mage::register(‘isSecureArea’, true),删除产品后移除它。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 26 Oct 2015 12:52:37 +0000
      <![CDATA[如何获取Magento中所有启用的支付模块]]> https://www.360magento.com/blog/active-payment-modules/ 下面的代码将获取你所有启用的Magento支付模块。下面的例子返回一个数组,你可以用它在Magento的前后台创建一个下拉框或者别的东西。

      class Alwayly_Vendor_Model_Activpayment
      {
       
       
      	public function getActivPaymentMethods()
      	{
      	   $payments = Mage::getSingleton('payment/config')->getActiveMethods();
       
      	   $methods = array(array('value'=>'', 'label'=>Mage::helper('adminhtml')->__('--Please Select--')));
       
      	   foreach ($payments as $paymentCode=>$paymentModel) {
                  $paymentTitle = Mage::getStoreConfig('payment/'.$paymentCode.'/title');
                  $methods[$paymentCode] = array(
                      'label'   => $paymentTitle,
                      'value' => $paymentCode,
                  );
              }
       
              return $methods;
       
      	} 
       
      }
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 25 Oct 2015 12:31:59 +0000
      <![CDATA[更改Magento后台网格行数]]> https://www.360magento.com/blog/admin-grid-rows/ 我们从客户那里接到一个需求,让我们更改Magento后台网格显示的行数。现在,这非常简单,我们知道如何做。下面的例子中,我们将使用Magento观测者模型和事件“core_block_abstract_prepare_layout_before”

      首先,给你的文件做好备份。

      这是事件的例子,将下面的代码放入到config.xml

      <adminhtml>
              <events>            
                  <core_block_abstract_prepare_layout_before>
          		<observers>
                          <reward>
                              <class>grid/observer</class>
                              <method>applyLimitToGrid</method>
                          </reward>
                      </observers>
          	    </core_block_abstract_prepare_layout_before>
              </events>
      </adminhtml>
      

      第二步

      创建模型类observer.php

      class Alwayly_Grid_Model_Observer
      {
       
          public function applyLimitToGrid(Varien_Event_Observer $observer)
          {
          	$block = $observer->getEvent()->getBlock();
          	if(($block instanceof Mage_Adminhtml_Block_Widget_Grid) &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; !($block  instanceof Mage_Adminhtml_Block_Dashboard_Grid))
          	$block->setDefaultLimit(200);
       
          }
       
      }
      

      如果你知道如何创建Magento模块,那么最好将这些代码写入你自己的模块。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 25 Oct 2015 12:28:06 +0000
      <![CDATA[为Magento网格中的自定义列添加自定义渲染器]]> https://www.360magento.com/blog/magento-custom-renderer/ 有时你会需要在Magento的一些网格中添加新列,这是个很简单的任务。但是你可能想按你的方式格式化值或者别的什么。那么写你自己的渲染器就十分有用和简单了。

      那么实际情况该如何做呢?让我们看看后台产品列表网格。在/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Grid.php文件中被称为Mage_Adminhtml_Block_Catalog_Product_Grid的类。在这篇文章中我们不重写这个块,但是让你知道如何做到这一点。用新的数据修改_prepareCollection()方法,例如,让我们为一个产品添加短描述。

      protected function _prepareCollection()
      {
      $store = $this->_getStore();
      $collection = Mage::getModel('catalog/product')->getCollection()
      ->addAttributeToSelect('sku')
      ->addAttributeToSelect('name')
      ->addAttributeToSelect('short_description') // THIS IS WHAT WE HAVE ADDED
      ->addAttributeToSelect('attribute_set_id')
      ->addAttributeToSelect('type_id')
      ->joinField('qty',
      'cataloginventory/stock_item',
      'qty',
      'product_id=entity_id',
      '{{table}}.stock_id=1',
      'left');
       
      if ($store->getId()) {
      //$collection->setStoreId($store->getId());
      $collection->addStoreFilter($store);
      $collection->joinAttribute('custom_name', 'catalog_product/name', 'entity_id', null, 'inner', $store->getId());
      $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner', $store->getId());
      $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner', $store->getId());
      $collection->joinAttribute('price', 'catalog_product/price', 'entity_id', null, 'left', $store->getId());
      }
      else {
      $collection->addAttributeToSelect('price');
      $collection->addAttributeToSelect('status');
      $collection->addAttributeToSelect('visibility');
      }
       
      $this->setCollection($collection);
       
      parent::_prepareCollection();
      $this->getCollection()->addWebsiteNamesToResult();
      return $this;
      }
      

      现在,让我们把这些添加到一个新的列:

      *You will find some more code inside this method, but for readability purposes, I'll just say you need to add code you find 
      
      here at beginning of this method...*/
       
      protected function _prepareColumns()
      {
      $this->addColumn('Short description',
      array(
      'header'=> Mage::helper('catalog')->__('Short description'),
      'index' => 'short_description',
      'renderer'  => 'Mage_Adminhtml_Block_Catalog_Product_Renderer_Red',// THIS IS WHAT THIS POST IS ALL ABOUT
      ));
       
      }
      

      创建Mage_Adminhtml_Block_Catalog_Product_Renderer_Red 类,其代码如下

      < ?php
      class Mage_Adminhtml_Block_Catalog_Product_Renderer_Red extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
      {
       
      public function render(Varien_Object $row)
      {
      $value =  $row->getData($this->getColumn()->getIndex());
      return '<span style="color:red;">'.$value.'';
       
      }
       
      }
      ?>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 24 Oct 2015 14:31:43 +0000
      <![CDATA[用PHP-ExcelReader类来读取XLS文件到Magento模块]]> https://www.360magento.com/blog/excelreader-load-xls/ 最近遇上一个不小的问题,我要读取XLS(Microsoft Excel文件)到PHP。在我花了近两个小时在网上搜索以后,我发现了一个开源的“PHP-ExcelReader class”很不错。它有所有我需要的东西(多表支持,可读取EXCEL 2000和2007的数据),另一方面,Magento不支持XLS。我决定些一个小的方法,这样你就可以在任何Magento的类里执行了。

      那么,下面就是代码了:

      public function loadXML($path_to_XML)
      {
      $include_path = dirname(__FILE__);
      $path_to_PHP_ExcelReader = $include_path."/read_xls/Excel/reader.php";
       
      require_once $path_to_PHP_ExcelReader;
       
      // ExcelFile($filename, $encoding);
      $data = new Spreadsheet_Excel_Reader();
       
      // Set output Encoding.
      $data->setOutputEncoding('utf-8');
      /* if you want you can change 'iconv' to mb_convert_encoding:*/
       
      $data->setUTFEncoder('mb');
       
      /*
      * By default rows & cols indeces start with 1
      * For change initial index use:
      */
      $index = 0;
       
      $data->setRowColOffset($index);
      /* setDefaultFormat - set format for columns with unknown formatting*/
       
      $data->setDefaultFormat('%.2f');
       
      /* setColumnFormat - set format for column (apply only to number fields)*/
      $data->setColumnFormat(4, '%.3f');
      /*Do the actual reading of file*/
       
      $data->read($path_to_XML);
      return $data;
      }
      

      下面是你的Excel文件数据化为PHP数组后可以调用的方法:

      $data->sheets[0]['numRows']
      //count rows
       
      $data->sheets[0]['numCols']
      //count columns
       
      $data->sheets[0]['cells'][$i][$j]
      //data from $i-row $j-column
       
      $data->sheets[0]['cellsInfo'][$i][$j]
      //extended info about cell
       
      $data->sheets[0]['cellsInfo'][$i][$j]['type'] = "date" | "number" | "unknown"
      //if 'type' == "unknown" - use 'raw' value, because  cell contain value with format '0.00';
      $data->sheets[0]['cellsInfo'][$i][$j]['raw'] = value
      //if cell without format
       
      $data->sheets[0]['cellsInfo'][$i][$j]['colspan']
      //gets colspan value
       
      $data->sheets[0]['cellsInfo'][$i][$j]['rowspan']
      //gets rowspan value
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 24 Oct 2015 14:12:33 +0000
      <![CDATA[在Magento核心动作前后调用事件]]> https://www.360magento.com/blog/before-after-events/ 正如我们所知的,Magento中有些事件被默认地调度。我们可以轻易地挂钩这些事件,但这不是这篇文章的主题。我们要尝试的是在一些Magento控制器的一些动作前后添加自定义事件。

      这样,我们就不需要事件被默认调度。当然,有些事件需要多做一点处理(例如,如果你需要一些session的东西,session在动作之后要被清除),但是大部分情况,有一种方法可以从事件中获取我们想要的。

      例如,“Mage_Checkout_CartController”中的“addAction()”方法,我们可以用标准的方式重写这个方法并在重写的类里调度我们的事件。但我们可以做些类似这样的事情。

      添加下面的代码到你模块的config.xml文件:

      < ?xml version="1.0"?>
      <config>
          <global>
              <models>
                  <dispatcher>
                      <class>Alwayly_Dispatcher_Model</class>
                  </dispatcher>
              </models>
          </global>
          <frontend>
              <events>
                  <!-- Hooking to Magento's default event "controller_action_predispatch" -->
                  <controller_action_predispatch>
                      <observers>
                          <controller_action_before>
                              <class>dispatcher/observer</class>
                              <method>hookToControllerActionPreDispatch</method>
                          </controller_action_before>
                      </observers>
                  </controller_action_predispatch>
                  <!-- Hooking to Magento's default event "controller_action_postdispatch" -->
                  <controller_action_postdispatch>
                      <observers>
                          <controller_action_after>
                              <class>dispatcher/observer</class>
                              <method>hookToControllerActionPostDispatch</method>
                          </controller_action_after>
                      </observers>
                  </controller_action_postdispatch>
                  <!-- Hooking to our own event "add_to_cart_before" -->
                  <add_to_cart_before>
                      <observers>
                          <add_to_cart_before>
                              <class>dispatcher/observer</class>
                              <method>hookToAddToCartBefore</method>
                          </add_to_cart_before>
                      </observers>
                  </add_to_cart_before>
                  <!-- Hooking to our own event "add_to_cart_after" -->
                  <add_to_cart_after>
                      <observers>
                          <add_to_cart_after>
                              <class>dispatcher/observer</class>
                              <method>hookToAddToCartAfter</method>
                          </add_to_cart_after>
                      </observers>
                  </add_to_cart_after>
              </events>
          </frontend>
      </config>
      

      添加下面的代码到你模块的Observer.php

      class Alwayly_Dispatcher_Model_Observer
      {
          //this is hook to Magento's event dispatched before action is run
          public function hookToControllerActionPreDispatch($observer)
          {
              //we compare action name to see if that's action for which we want to add our own event
              if($observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add') 
              {
                  //We are dispatching our own event before action ADD is run and sending parameters we need
                  Mage::dispatchEvent("add_to_cart_before", array('request' => $observer->getControllerAction()->getRequest()));
              }
          }
       
          public function hookToControllerActionPostDispatch($observer)
          {
               //we compare action name to see if that's action for which we want to add our own event 
              if($observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add') 
              {
                  //We are dispatching our own event before action ADD is run and sending parameters we need
                  Mage::dispatchEvent("add_to_cart_after", array('request' => $observer->getControllerAction()->getRequest()));
              }
          }
       
       	public function hookToAddToCartBefore($observer) 
      	{   
                  //Hooking to our own event
      	    $request = $observer->getEvent()->getRequest()->getParams();
                  // do something with product
      	    Mage::log("Product ".$request['product']." will be added to cart.");
      	}
       
      	public function hookToAddToCartAfter($observer) 
      	{
                  //Hooking to our own event
      	    $request = $observer->getEvent()->getRequest()->getParams();
                  // do something with product
      	    Mage::log("Product ".$request['product']." is added to cart.");
      	}
      }
      

      最后,我要指出的是:这段代码没有在产品环境中做测试,我们只是添加了两个自定义事件在Magento核心动作的前后,而不必重写这个类。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 23 Oct 2015 11:49:34 +0000
      <![CDATA[如何扩展Magento核心控制器]]> https://www.360magento.com/blog/extend-magento-controller/ 今天我将演示如何在不弄乱核心文件本身的前提下编辑Magento核心模块。

      我选择Magento Customer模块下的Account控制器作为本文的示例。你要先找出它在Magento核心文件夹里的路径(完整路径是:app/code/core/Mage/Customer/controllers/AccountController.php)。

      首先创建有类似文件结构的文件:

      app/code/local/Alwayly/Coreextended/controllers/Frontend/Customer/AccountController.php。(当然,你可以把Alwayly替换成你想要的命名空间,Coreextended换成其它模块名,但你需要对其它部分做相应的修改)。

      接着创建我们模块的xml文件:app/code/local/Alwayly/Coreextended/etc/config.xml。将下面的代码写入对应的文件中:

      1.AccountController.php:

      < ?php
      require_once Mage::getModuleDir('controllers', 'Mage_Customer').DS.'AccountController.php';
      //we need to add this one since Magento wont recognize it automatically
      
      class Alwayly_Coreextended_Frontend_Customer_AccountController extends Mage_Customer_AccountController
      {//here, you extended the core controller with our public function indexAction()
      {
      parent::indexAction();
      //you can always use default functionality
      }
      
      public function myactionAction()
      {
      //my code
      //you can write your own methods / actions
      }
      
      public function mymethod()
      {
      //my code
      //you can write your own methods
      }
      
      public function loginAction()
      {
      //finally you can write your code that will rewrite the whole core method
      //and you can call for your own methods, as you have full control over core controller
      }
      }
      

      2.config.xml:

      <?xml version="1.0"?>
      <config>
          <modules>
              <alwayly_coreextended>
                  <version>0.2.0</version>
              </alwayly_coreextended>
          </modules>
          <frontend>
              <routers>
                  <customer>
                      <args>
                          <modules>
                              <alwayly_coreextended before="Mage_Customer_AccountController">
                                     Alwayly_Coreextended_Frontend_Customer
                              </alwayly_coreextended>
                          </modules>
                      </args>
                  </customer>
              </routers>
          </frontend>
      </config>
      

      3.Alwayly_Coreextended.xml:

      < ?xml version="1.0"?>
      <!--we need to enable this module as any other if-->
      <!--you wish to do it as standalone module extension-->
      <config>
          <modules>
              <alwayly_coreextended>
                  <active>true</active>
                  <codepool>local</codepool>
              </alwayly_coreextended>
          </modules>
      </config>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 23 Oct 2015 11:42:46 +0000
      <![CDATA[以编程的方式修改magento核心配置数据]]> https://www.360magento.com/blog/programmatically-core-config/ Magento安装完成后一定有一些设置好的核心配置。当你从后台面板更新这些值的时候,数据会被保存到core_config_data到这张数据表。这看起来很重要,也是你不会去碰触的,是嘛?在有些情况下,你想要用代码直接修改设置,这篇文章就将演示如何去做。

      假设我们想将“demo store notice” (on/off)的值从0改为1。你可以打开你的数据库,进入“core_config_data“表,改变这个数据的值,然后保存。好吧,下面就是我要讲的代码,你可以在你代码的任何一位置调用它:

      $alwaylySwitch = new Mage_Core_Model_Config();
      /*
      *turns notice on
      */
      $alwaylySwitch ->saveConfig('design/head/demonotice', "1", 'default', 0);
      /*
      *turns notice off
      */
      $alwaylySwitch ->saveConfig('design/head/demonotice', "0", 'default', 0);
      

      实现这一神奇功能的代码是:

      class Mage_Core_Model_Config
      {
      	.
      	.
      	.
       
      	/**
           * Save config value to DB
           *
           * @param string $path
           * @param string $value
           * @param string $scope
           * @param int $scopeId
           * @return Mage_Core_Store_Config
           */
          public function saveConfig($path, $value, $scope = 'default', $scopeId = 0)
          {
              $resource = $this->getResourceModel();
              $resource->saveConfig(rtrim($path, '/'), $value, $scope, $scopeId);
       
              return $this;
          }
       
      	.
      	.
      	.
      }
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 22 Oct 2015 11:23:37 +0000
      <![CDATA[给Magento PDF发票添加自定义属性]]> https://www.360magento.com/blog/magentos-invoice-attribute/ 今天我将用短短的几步添加自定义属性到Magento的PDF发票。最近我有个任务是为产品创建一个名称为“alwayly_warehouse_location”的自定义属性,当点击“打印”(在后台发票区域)事件时输出它。由于发票打印是Magento核心功能,所以我们需要重写它。

      第一步

      在你的Magento项目中创建下面的文件:

      • app/code/local/Alwayly/Invoice/Model/Order/Pdf/Items/Invoice/Default.php
      • app/code/local/Alwayly/Invoice/Model/Order/Pdf/Invoice.php
      • app/code/local/Alwayly/Invoice/etc/config.xml

      这些是用来修改Magento核心功能的。

      第二步

      将下面代码加入到对应的文件中去: config.xml

      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Invoice>
                  <version>0.1.0</version>
              </Alwayly_Invoice>
          </modules>
          <global>
              <models>
                  <sales>
                      <rewrite>
                          <order_pdf_invoice>Alwayly_Invoice_Model_Order_Pdf_Invoice</order_pdf_invoice>                <order_pdf_items_invoice_default>Alwayly_Invoice_Model_Order_Pdf_Items_Invoice_Default</order_pdf_items_invoice_default>
                      </rewrite>
                  </sales>
              </models>
          </global>
      </config>
      

      Default.php

      <?php
      /**
       * Alwayly PDF rewrite for custom attribute
       * Attribute "alwayly_warehouse_location" has to be set manually
       * Original: Sales Order Invoice Pdf default items renderer
       *
       * @category   Alwayly
       * @package    Inhoo_Invoice
       */
       
      class Alwayly_Invoice_Model_Order_Pdf_Items_Invoice_Default extends Mage_Sales_Model_Order_Pdf_Items_Invoice_Default
      {
          /**
           * Draw item line
      	 **/
          public function draw()
          {
              $order  = $this->getOrder();
              $item   = $this->getItem();
              $pdf    = $this->getPdf();
              $page   = $this->getPage();
              $lines  = array();
       
      		//Alwayly - Added custom attribute to PDF, first get it if exists
      		$WarehouseLocation = $this->getWarehouseLocationValue($item);
       
              // draw Product name
              $lines[0] = array(array(
                  'text' => Mage::helper('core/string')->str_split($item->getName(), 60, true, true),
                  'feed' => 35,
              ));
       
      		//Alwayly - Added custom attribute
      		//draw Warehouse Location
              $lines[0][] = array(
                  'text'  => Mage::helper('core/string')->str_split($WarehouseLocation, 25),
                  'feed'  => 245
              );
       
              // draw SKU
              $lines[0][] = array(
                  'text'  => Mage::helper('core/string')->str_split($this->getSku($item), 25),
                  'feed'  => 325
              );
       
              // draw QTY
              $lines[0][] = array(
                  'text'  => $item->getQty()*1,
                  'feed'  => 435
              );
       
              // draw Price
              $lines[0][] = array(
                  'text'  => $order->formatPriceTxt($item->getPrice()),
                  'feed'  => 395,
                  'font'  => 'bold',
                  'align' => 'right'
              );
       
              // draw Tax
              $lines[0][] = array(
                  'text'  => $order->formatPriceTxt($item->getTaxAmount()),
                  'feed'  => 495,
                  'font'  => 'bold',
                  'align' => 'right'
              );
       
              // draw Subtotal
              $lines[0][] = array(
                  'text'  => $order->formatPriceTxt($item->getRowTotal()),
                  'feed'  => 565,
                  'font'  => 'bold',
                  'align' => 'right'
              );
       
              // custom options
              $options = $this->getItemOptions();
              if ($options) {
                  foreach ($options as $option) {
                      // draw options label
                      $lines[][] = array(
                          'text' => Mage::helper('core/string')->str_split(strip_tags($option['label']), 70, true, true),
                          'font' => 'italic',
                          'feed' => 35
                      );
       
                      if ($option['value']) {
                          $_printValue = isset($option['print_value']) ? $option['print_value'] : strip_tags($option['value']);
                          $values = explode(', ', $_printValue);
                          foreach ($values as $value) {
                              $lines[][] = array(
                                  'text' => Mage::helper('core/string')->str_split($value, 50, true, true),
                                  'feed' => 40
                              );
                          }
                      }
                  }
              }
       
              $lineBlock = array(
                  'lines'  => $lines,
                  'height' => 10
              );
       
              $page = $pdf->drawLineBlocks($page, array($lineBlock), array('table_header' => true));
              $this->setPage($page);
       
          }
       
      	/*
      	 * Return Value of custom attribute
      	 * */
      	private function getWarehouseLocationValue($item)
      	{
      		$prod = Mage::getModel('catalog/product')->load($item->getProductId());
       
      		if(!($return_location = $prod->getAlwaylyWarehouseLocation()))
      			return 'N/A';
      		else
      			return $return_location;
      	}
      }
      

      Invoice.php

      <?php
      /**
       * Alwayly PDF rewrite for custom attribute
       * * Attribute "alwayly_warehouse_location" has to be set manually
       * Original: Sales Order Invoice PDF model
       *
       * @category   Alwayly
       * @package    Alwayly_Invoice
       */
      class Alwayly_Invoice_Model_Order_Pdf_Invoice extends Mage_Sales_Model_Order_Pdf_Invoice
      {
      	public function getPdf($invoices = array())
          {
              $this->_beforeGetPdf();
              $this->_initRenderer('invoice');
       
              $pdf = new Zend_Pdf();
              $this->_setPdf($pdf);
              $style = new Zend_Pdf_Style();
              $this->_setFontBold($style, 10);
       
              foreach ($invoices as $invoice) {
                  if ($invoice->getStoreId()) {
                      Mage::app()->getLocale()->emulate($invoice->getStoreId());
                  }
                  $page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
                  $pdf->pages[] = $page;
       
                  $order = $invoice->getOrder();
       
                  /* Add image */
                  $this->insertLogo($page, $invoice->getStore());
       
                  /* Add address */
                  $this->insertAddress($page, $invoice->getStore());
       
                  /* Add head */
                  $this->insertOrder($page, $order, Mage::getStoreConfigFlag(self::XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID, $order->getStoreId()));
       
                  $page->setFillColor(new Zend_Pdf_Color_GrayScale(1));
                  $this->_setFontRegular($page);
                  $page->drawText(Mage::helper('sales')->__('Invoice # ') . $invoice->getIncrementId(), 35, 780, 'UTF-8');
       
                  /* Add table */
                  $page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
                  $page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
                  $page->setLineWidth(0.5);
       
                  $page->drawRectangle(25, $this->y, 570, $this->y -15);
                  $this->y -=10;
       
                  /* Add table head */
                  $page->setFillColor(new Zend_Pdf_Color_RGB(0.4, 0.4, 0.4));
                  $page->drawText(Mage::helper('sales')->__('Products'), 35, $this->y, 'UTF-8');
      			//Added for custom attribute "alwayly_warehouse_location"
                  $page->drawText(Mage::helper('sales')->__('Warehouse Location'), 245, $this->y, 'UTF-8');
      			$page->drawText(Mage::helper('sales')->__('SKU'), 325, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('Price'), 380, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('Qty'), 430, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('Tax'), 480, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('Subtotal'), 535, $this->y, 'UTF-8');
       
                  $this->y -=15;
       
                  $page->setFillColor(new Zend_Pdf_Color_GrayScale(0));
       
                  /* Add body */
                  foreach ($invoice->getAllItems() as $item){
                      if ($item->getOrderItem()->getParentItem()) {
                          continue;
                      }
       
                      if ($this->y < 15) {
                          $page = $this->newPage(array('table_header' => true));
                      }
       
                      /* Draw item */
                      $page = $this->_drawItem($item, $page, $order);
                  }
       
                  /* Add totals */
                  $page = $this->insertTotals($page, $invoice);
       
                  if ($invoice->getStoreId()) {
                      Mage::app()->getLocale()->revert();
                  }
              }
              $this->_afterGetPdf();
       
              return $pdf;
          }
       
      	public function newPage(array $settings = array())
          {
              /* Add new table head */
              $page = $this->_getPdf()->newPage(Zend_Pdf_Page::SIZE_A4);
              $this->_getPdf()->pages[] = $page;
              $this->y = 800;
       
              if (!empty($settings['table_header'])) {
                  $this->_setFontRegular($page);
                  $page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
                  $page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
                  $page->setLineWidth(0.5);
                  $page->drawRectangle(25, $this->y, 570, $this->y-15);
                  $this->y -=10;
       
                  $page->setFillColor(new Zend_Pdf_Color_RGB(0.4, 0.4, 0.4));
                  $page->drawText(Mage::helper('sales')->__('Product'), 35, $this->y, 'UTF-8');
      			//Added for custom attribute "alwayly_warehouse_location"
      			$page->drawText(Mage::helper('sales')->__('Warehouse Location'), 245, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('SKU'), 325, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('Price'), 380, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('Qty'), 430, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('Tax'), 480, $this->y, 'UTF-8');
                  $page->drawText(Mage::helper('sales')->__('Subtotal'), 535, $this->y, 'UTF-8');
       
                  $page->setFillColor(new Zend_Pdf_Color_GrayScale(0));
                  $this->y -=20;
              }
              return $page;
          }
      }
      

      第三步

      进入后台 “Sales->Invoices->(View any of them)->Print”。下载PDF后可在每个订单物品中看到“Warehouse Location”

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 22 Oct 2015 11:17:10 +0000
      <![CDATA[为你的Magento插件创建配置]]> https://www.360magento.com/blog/magento-extension-configuration/ 今天,我想讲讲初学者如何在Magento配置区域创建一个简单的插件配置。首先,你需要一个插件。如果你是初学者,不知道如果创建你自己的插件,你可以看看网站里的其它文章。但我建议从一个新的插件开始,用于测试……

      第一步,添加(或者修改)你的system.xml文件:

      <?xml version="1.0" encoding="UTF-8"?>
      <config>
          <tabs>
              <alwayly translate="label" module="mymodule">
                  <label>Alwayly Extensions</label>
                  <sort_order>100</sort_order>
              </alwayly>
          </tabs>
          <sections>
              <alwayly translate="label" module="mymodule">
                  <label>Extension Options</label>
                  <tab>alwayly</tab>
                  <sort_order>1000</sort_order>
                  <show_in_default>1</show_in_default>
                  <show_in_website>1</show_in_website>
                  <show_in_store>1</show_in_store>
       
                  <groups>
                      <alwayly_group translate="label" module="mymodule">
                          <label>My Extension Options</label>
                          <frontend_type>text</frontend_type>
                          <sort_order>1000</sort_order>
                          <show_in_default>1</show_in_default>
                          <show_in_website>1</show_in_website>
                          <show_in_store>1</show_in_store>
       
                          <fields>
                              <alwayly_input translate="label">
                                  <label>My Input Field: </label>
                                  <comment>My Comment</comment>
                                  <frontend_type>text</frontend_type>
                                  <sort_order>20</sort_order>
                                  <show_in_default>1</show_in_default>
                                  <show_in_website>1</show_in_website>
                                  <show_in_store>1</show_in_store>
                              </alwayly_input>
                              <alwayly_select translate="label">
                                  <label>My Dropdown: </label>
                                  <comment>Source model provider Magento's default Yes/No values</comment>
                                  <frontend_type>select</frontend_type>
                                  <sort_order>90</sort_order>
                                  <show_in_default>1</show_in_default>
                                  <show_in_website>1</show_in_website>
                                  <show_in_store>1</show_in_store>
                                  <source_model>adminhtml/system_config_source_yesno</source_model>
                              </alwayly_select>
                          </fields>
                      </alwayly_group>
                  </groups>
              </alwayly>
          </sections>
      </config>
      

      第二步,为了使用Magento配置区域,你需要编辑你的config.xml文件并定义模型和助手:

      <config>
          <modules>
              <Alwayly_Mymodule>
                  <version>0.1.0</version>
              </Alwayly_Mymodule>
          </modules>
          <global>
              <models>
                  <mymodule>
                      <class>Alwayly_Mymodule_Model</class>
                  </mymodule>
              </models>
              <helpers>
                  <mymodule>
                      <class>Alwayly_Mymodule_Helper</class>
                  </mymodule>
              </helpers>
           </global>
      </config>
      

      最后你需要再次编辑插件的config.xml文件,加入 “”标签:

      <adminhtml>
          <acl>
              <resources>
                  <all>
                      <title>Allow Everything</title>
                  </all>
                  <admin>
                      <children>
                          <system>
                              <children>
                                  <config>
                                      <children>
                                          <alwayly>
                                              <title>Alwayly - All</title>
                                          </alwayly>
                                      </children>
                                  </config>
                              </children>
                          </system>
                      </children>
                  </admin>
              </resources>
          </acl>
      </adminhtml>
      

      要检索你保存的配置,你应该使用像这样的代码:

      Mage::getStoreConfig('alwayly/alwayly_group/alwayly_input',Mage::app()->getStore());
      

      或者这样:

      Mage::getStoreConfig('alwayly/alwayly_group/alwayly_select',Mage::app()->getStore());
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 21 Oct 2015 12:15:10 +0000
      <![CDATA[Magento中为自定义控制器布局]]> https://www.360magento.com/blog/layout-magento-controller/ 当你用到Magento中的自定义控制器(不论前台还是后台)时,你可能会使用现有的块和模型,或者需要重写类。但当你想要移动、删除常见块的时候会发生什么呢?你真的能设计你的网页视图而不需要触及层叠样式表(CSS)?

      事实上,是的你可以以一种相当简单的方式做到。前提是你知道你控制器的句柄。

      要获取你控制器的句柄,你需要一些调试技术。在你控制器的动作里加入下面代码:

       Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
      

      它以同样的方式作用于前端和后台。你自定义的动作看起来像这样:

      public function indexAction()
      {
              $this->loadLayout();
              $this->renderLayout();
              Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
      }
      

      在你的浏览器输出,你可能会得到这样的结果:

      前端控制器:

      array(5) {
        [0] => string(7) "default"
        [1] => string(13) "STORE_default"
        [2] => string(29) "THEME_frontend_default_hybrid"
        [3] => string(29) "alwayly_developers_index_index"
        [4] => string(19) "customer_logged_out"
      }
      

      后台控制器:

      array(4) {
        [0] => string(7) "default"
        [1] => string(11) "STORE_admin"
        [2] => string(30) "THEME_adminhtml_default_inchoo"
        [3] => string(28) "adminhtml_switch_index_index"
      }
      

      你需要数组中第四项的值。

      前端:

       [3] => string(29) "alwayly_developers_index_index"
      

      后台:

       [3] => string(28) "adminhtml_switch_index_index"
      

      现在,你了解了句柄之后,我们开始你的布局文件。在你主题的布局文件夹里创建“local.xml”布局文件。在我简单的例子里,我移除头部和底部,前端和后台。

      前端示例:app/design/frontend/default/default/layout/local.xml

      < ?xml version="1.0"?>
      <!--
      /**
       * Magento
       *
       * @category    Alwayly
       * @package     Alwayly_Developers
       */
      -->
      <layout>
       
          <alwayly_developers_index_index>
      	<remove name="header" />
          	<remove name="footer" />
          </alwayly_developers_index_index>
       
      </layout>
      

      后台示例:app/design/adminhtml/default/default/layout/local.xml

      < ?xml version="1.0"?>
      <!--
      /**
       * Magento
       *
       * @category    Alwayly
       * @package     Alwayly_Developers
       */
      -->
      <layout>
       
          <adminhtml_switch_index_index>
      	<remove name="header" />
          	<remove name="footer" />
          </adminhtml_switch_index_index>
       
      </layout>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 21 Oct 2015 12:05:29 +0000
      <![CDATA[如何扩展Magento订单网格]]> https://www.360magento.com/blog/extend-order-grid/ 这里是一个小示例来解释如何修改订单网格。订单网格的主类是“Mage_Adminhtml_Block_Sales_Order_Grid”,如果你想添加一些列,你必须重写这个类(块)。

      如何重写magento块

      <blocks>
          <adminhtml>
              <rewrite>
                  <sales_order_grid>Alwayly_Test_Block_Adminhtml_Order_Grid</sales_order_grid>
              </rewrite>
          </adminhtml>
      </blocks>
      

      如果你调用“adminhtml/sales_order_grid”,你将获取Alwayly_Test_Block_Adminhtml_Order_Grid,那么创建Alwayly_Test_Block_Adminhtml_Order_Grid吧。下面是我的代码:

      < ?php
      class Alwayly_Test_Block_Adminhtml_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid
      {
           public function __construct()
          {
              parent::__construct();
              $this->setId('sales_order_grid');
              $this->setUseAjax(true);
              $this->setDefaultSort('created_at');
              $this->setDefaultDir('DESC');
              $this->setSaveParametersInSession(true);
          }
       
          /**
           * Retrieve collection class
           *
           * @return string
           */
          protected function _getCollectionClass()
          {
              return 'sales/order_grid_collection';
          }
       
          protected function _prepareCollection()
          {
              $collection = Mage::getResourceModel($this->_getCollectionClass());
       
              //we changed mysql query, we added inner join to order item table
              $collection->join('sales/order_item', 'order_id=entity_id', array('name'=>'name', 'sku' =>'sku', 'qty_ordered'=>'qty_ordered' ), null,'left');
              $this->setCollection($collection);
              return parent::_prepareCollection();
          }
       
          protected function _prepareColumns()
          {
       
              $this->addColumn('real_order_id', array(
                  'header'=> Mage::helper('sales')->__('Order #'),
                  'width' => '80px',
                  'type'  => 'text',
                  'index' => 'increment_id',
              ));
       
              if (!Mage::app()->isSingleStoreMode()) {
                  $this->addColumn('store_id', array(
                      'header'    => Mage::helper('sales')->__('Purchased from (store)'),
                      'index'     => 'store_id',
                      'type'      => 'store',
                      'store_view'=> true,
                      'display_deleted' => true,
                      'filter_index' => 'main_table.store_id'
                  ));
              }
       
              $this->addColumn('created_at', array(
                  'header' => Mage::helper('sales')->__('Purchased On'),
                  'index' => 'created_at',
                  'type' => 'datetime',
                  'width' => '100px',
                  'filter_index' => 'main_table.created_at'
              ));
       
              $this->addColumn('billing_name', array(
                  'header' => Mage::helper('sales')->__('Bill to Name'),
                  'index' => 'billing_name',
              ));
       
              $this->addColumn('qty_ordered', array(
                  'header'    => Mage::helper('sales')->__('Items Ordered'),
                  'index'     => 'qty_ordered',
                  'type'      => 'number',
                  'total'     => 'sum'
              ));
       
              $this->addColumn('sku', array(
                  'header'    => Mage::helper('catalog')->__('SKU'),
                  'index'     => 'sku',
      			'type' => 'text'
              ));
       
              $this->addColumn('base_grand_total', array(
                  'header' => Mage::helper('sales')->__('G.T. (Base)'),
                  'index' => 'base_grand_total',
                  'type'  => 'currency',
                  'currency' => 'base_currency_code',
              ));
       
              $this->addColumn('grand_total', array(
                  'header' => Mage::helper('sales')->__('G.T. (Purchased)'),
                  'index' => 'grand_total',
                  'type'  => 'currency',
                  'currency' => 'order_currency_code',
              ));
       
              $this->addColumn('status', array(
                  'header' => Mage::helper('sales')->__('Status'),
                  'index' => 'status',
                  'type'  => 'options',
                  'width' => '70px',
                  'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
              ));
       
       
              return $this;
          }
       
          protected function _prepareMassaction()
          {
              $this->setMassactionIdField('entity_id');
              $this->getMassactionBlock()->setFormFieldName('order_ids');
              $this->getMassactionBlock()->setUseSelectAll(false);
       
              if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/cancel')) {
                  $this->getMassactionBlock()->addItem('cancel_order', array(
                       'label'=> Mage::helper('sales')->__('Cancel'),
                       'url'  => $this->getUrl('*/sales_order/massCancel'),
                  ));
              }
       
              if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/hold')) {
                  $this->getMassactionBlock()->addItem('hold_order', array(
                       'label'=> Mage::helper('sales')->__('Hold'),
                       'url'  => $this->getUrl('*/sales_order/massHold'),
                  ));
              }
       
              if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/unhold')) {
                  $this->getMassactionBlock()->addItem('unhold_order', array(
                       'label'=> Mage::helper('sales')->__('Unhold'),
                       'url'  => $this->getUrl('*/sales_order/massUnhold'),
                  ));
              }
       
              $this->getMassactionBlock()->addItem('pdfinvoices_order', array(
                   'label'=> Mage::helper('sales')->__('Print Invoices'),
                   'url'  => $this->getUrl('*/sales_order/pdfinvoices'),
              ));
       
              $this->getMassactionBlock()->addItem('pdfshipments_order', array(
                   'label'=> Mage::helper('sales')->__('Print Packingslips'),
                   'url'  => $this->getUrl('*/sales_order/pdfshipments'),
              ));
       
              $this->getMassactionBlock()->addItem('pdfcreditmemos_order', array(
                   'label'=> Mage::helper('sales')->__('Print Credit Memos'),
                   'url'  => $this->getUrl('*/sales_order/pdfcreditmemos'),
              ));
       
              $this->getMassactionBlock()->addItem('pdfdocs_order', array(
                   'label'=> Mage::helper('sales')->__('Print All'),
                   'url'  => $this->getUrl('*/sales_order/pdfdocs'),
              ));
       
              return $this;
          }
       
          public function getRowUrl($row)
          {
              if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
                  return $this->getUrl('*/sales_order/view', array('order_id' => $row->getId()));
              }
              return false;
          }
          public function getGridUrl()
          {
              return $this->getUrl('*/*/grid', array('_current'=>true));
          }
      }
      

      如果你想添加一些列,你需要添加下面的代码到 _prepareColumns方法:

      $this->addColumn('sku', array(
      'header'    => Mage::helper('catalog')->__('SKU'),
      'index'     => 'sku',
      'type' => 'text'
      ));
      

      如你所见,我们修改了_prepareCollection()方法。我们改变了SQL语句,连接了第二张数据表。这只是我的例子,你可以根据你的需求来修改SQL语句。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 20 Oct 2015 13:03:26 +0000
      <![CDATA[插入动态菜单到Magento后台]]> https://www.360magento.com/blog/dynamical-menu/ 最近Magento的一个核心功能(后台管理员菜单需要XML定义)让我觉得沮丧。我想要加一些快速的网站/店铺链接到后台。解决方法是重写Magento的一个后台块,然后连接我的动态菜单(没有XML)。如果你对此感兴趣,那么读下去。

      为了让它可升级,我决定做成插件。它值包含2个文件,config.xml和一个重写块。

      首先,创建config.xml,我的是这样的:

      <?xml version="1.0" encoding="UTF-8"?>
      <config>
          <modules>
              <Alwayly_ExtendedMenu>
                  <version>0.1.0</version>
              </Alwayly_ExtendedMenu>
          </modules>
          <global>
              <blocks>
                  <configurable>
                      <class>Alwayly_Configurable_Block</class>
                  </configurable>
                  <adminhtml>
                      <rewrite>
                          <page_menu>Alwayly_ExtendedMenu_Block_Adminhtml_Menu</page_menu>
                      </rewrite>
                  </adminhtml>
              </blocks>
          </global>
      </config>
      

      由于Magento一如既往地解析XML,对我来说理想的解决方法就是在输出菜单前与解析数据挂钩。所以,我之前提到的块是“Mage_Adminhtml_Block_Page_Menu”。我对getMenuArray方法比较感兴趣,它是这样的:

       /**
           * Retrieve Adminhtml Menu array
           *
           * @return array
           */
          public function getMenuArray()
          {
              return $this->_buildMenuArray();
          }
      
      

      这是最合适的地方来修改Magento核心,我用下面的代码创建了“Alwayly_ExtendedMenu_Block_Adminhtml_Menu”:

      <?php
      class Alwayly_ExtendedMenu_Block_Adminhtml_Menu extends Mage_Adminhtml_Block_Page_Menu
      {
      	public function getMenuArray()
      	{
      		//Load standard menu
      		$parentArr = parent::getMenuArray();
       
      		//Prepare "View Sites" menu
      		$parentArr['view_sites'] = array(
      			'label' => 'View Sites',
      			'active'=>false ,
      			'sort_order'=>0,
      			'click' => 'return false;',
      			'url'=>'#',
      			'level'=>0,
      			'last'=> true,
      			'children' => array()
      		);
       
      		$app = Mage::app();
       
      		$j = 0;
       
      		$allWebsites = $app->getWebsites();
      		$totalWebsiteCount = count($allWebsites) - 1;
       
      		foreach ($allWebsites as $_eachWebsiteId => $websiteVal){
      			$_storeName = $app->getWebsite($_eachWebsiteId)->getName();
      			$_websiteUrl = array(
      					'label' => $_storeName,
      					'active' => false ,
      					'url' => '#',
      					'click' => "return false",
      					'sort_order' => $j++ * 10,
      					'level' => 1,
      					'children' => array()
      					);
       
      			if(count($parentArr['view_sites']['children']) == $totalWebsiteCount){
      				$_websiteUrl['last'] = true;
      			} else {
      				$_websiteUrl['last'] = false;
      			}
       
      			$parentArr['view_sites']['children'][$j - 1] = $_websiteUrl;
       
      			$allStores = $app->getWebsite($app->getWebsite($_eachWebsiteId)->getId())->getStores();
      			$totalCount = count($allStores);
      			$i = 0;
      			foreach ($allStores as $_eachStoreId => $val){
      				$_websiteId = $app->getStore($_eachStoreId)->getWebsiteId();
      				if($_websiteId == $j){
      					$_storeName = $app->getStore($_eachStoreId)->getName();
      					$baseUrl = $app->getStore($_eachStoreId)->getUrl();
      					$_websiteUrl = array(
      							'label' => $_storeName,
      							'active' => false ,
      							'click' => "window.open(this.href, 'Website - ' + this.href); return false;",
      							'sort_order' => $i++ * 10,
      							'level' => 2,
      							'url' => $baseUrl
      							);
       
      					if(count($parentArr['view_sites']['children'][$j - 1]['children']) + 1 == $totalCount or $totalCount == 0)
      						$_websiteUrl['last'] = true;
      						else
      						$_websiteUrl['last'] = false;
       
      					$parentArr['view_sites']['children'][$j - 1]['children'][$i] = $_websiteUrl;
      				}
      			}
      		}
      		return $parentArr;
          }
      }
      

      我这里重写了父类方法“getMenuArray()”,我的动态菜单也在结果数组中。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 20 Oct 2015 12:52:05 +0000
      <![CDATA[为Magento数量框添加“+”,“-”功能]]> https://www.360magento.com/blog/magentos-quantity-increment/ 你也许注意到了Magento的数量输入只是普通的输入框,当你想要修改它的值时必须先手动删除现有值,然后输入新的值。今天我将展示添加加号和减号来修改数量。感兴趣的话就继续往下阅读吧。

      这是一项非常简单的工作,但又与Magento中的其它东西不一样,它需要些时间(我花了2小时测试)。我所做的就是创建一个连接JavaScript的插件。我动态地创建了div元素并用包含“+”和“-”号的段落标签来填充。

      负责执行的代码是这样的:

      var parentTD;
      	var newDiv;
      	var navigationDiv;
      	var i = 1;
      	var currentElement = null;
       
      	$$('input.qty').each(function(el){
      		parentTD = el.parentNode;
       
      		newDiv = document.createElement('div');
      		Element.extend(newDiv);
      		newDiv.id = i++;
      		newDiv.update(parentTD.innerHTML).innerHTML; //set new input inside new div
      		parentTD.update().innerHTML; //erase old input
      		parentTD.appendChild(newDiv); //show new div
       
      		navigationDiv = document.createElement('div');
      		Element.extend(navigationDiv);
      		navigationDiv.update('<p class="up">+</p><p class="dn">-</p>').innerHTML;
      		newDiv.appendChild(navigationDiv);
      	});
       
      	$$('p.up').each(function(el){
      		el.observe('click',function(event){
      			currentElement = el.parentNode.previous();
      			i = 0; //In case we get in to infinite loop
      			while(currentElement.type != 'text' && i < 5){
      				currentElement = currentElement.previous();
      				i++;
      			}
      			currentElement.value = parseInt(currentElement.value) + 1;
      		});
      	});
       
      	$$('p.dn').each(function(el){
      		el.observe('click',function(event){
      			currentElement = el.parentNode.previous();
      			i = 0; //In case we get in to infinite loop
      			while(currentElement.type != 'text' && i < 5){
      				currentElement = currentElement.previous();
      				i++;
      			}
      			if(parseInt(currentElement.value) > 0){
      				currentElement.value = parseInt(currentElement.value) - 1;
      			}
      		});
      	});
      

      为安全起见,请先做好备份。执行之后是没有样式的,但是你可以随时添加一些CSS样式。生成的HTML结构大概是这样的:

      <div id="1">
      	<label for="qty">
      		Qty:
      	</label>
      	<input name="qty" id="qty" maxlength="12" value="1" title="Qty" class="input-text qty" type="text">
      	<button type="button" title="Add to Cart" class="button btn-cart" onclick="productAddToCartForm.submit(this)">
      		<span>
      			<span>
      				Add to Cart
      			</span>
      		</span>
      	</button>
      	<div>
      		<p class="up">
      			+
      		</p>
      		<p class="dn">
      			-
      		</p>
      	</div>
      </div>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 19 Oct 2015 12:46:38 +0000
      <![CDATA[Magento中如何添加新的自定义类别属性]]> https://www.360magento.com/blog/custom-category-attribute/ 有时候你需要扩展Magento的类别功能。有几种方法你可以达到目的,你可以直接修改和添加数据到表里,但如果你不知道怎么做的话就会浪费时间。这篇文章将演示如何通过sql_setup脚本来给你的Magento店铺添加新的自定义类别属性。

      示例Mysql setup脚本是这样的,你需要根据你的需求来修改新属性的配置。

      $installer = $this;
      $installer->startSetup();
       
      $entityTypeId     = $installer->getEntityTypeId('catalog_category');
      $attributeSetId   = $installer->getDefaultAttributeSetId($entityTypeId);
      $attributeGroupId = $installer->getDefaultAttributeGroupId($entityTypeId, $attributeSetId);
       
      $installer->addAttribute('catalog_category', 'new_cat_attrb',  array(
          'type'     => 'int',
          'label'    => 'New Category Attribute',
          'input'    => 'text',
          'global'   => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
          'visible'           => true,
          'required'          => false,
          'user_defined'      => false,
          'default'           => 0
      ));
       
       
      $installer->addAttributeToGroup(
          $entityTypeId,
          $attributeSetId,
          $attributeGroupId,
          'new_cat_attrb',
          '11'					//last Magento's attribute position in General tab is 10
      );
       
      $attributeId = $installer->getAttributeId($entityTypeId, 'new_cat_attrb');
       
      $installer->run("
      INSERT INTO `{$installer->getTable('catalog_category_entity_int')}`
      (`entity_type_id`, `attribute_id`, `entity_id`, `value`)
          SELECT '{$entityTypeId}', '{$attributeId}', `entity_id`, '1'
              FROM `{$installer->getTable('catalog_category_entity')}`;
      ");
       
       
      //this will set data of your custom attribute for root category
      Mage::getModel('catalog/category')
          ->load(1)
          ->setImportedCatId(0)
          ->setInitialSetupFlag(true)
          ->save();
       
      //this will set data of your custom attribute for default category
      Mage::getModel('catalog/category')
          ->load(2)
          ->setImportedCatId(0)
          ->setInitialSetupFlag(true)
          ->save();
       
      $installer->endSetup();
      

      在你模块的config.xml中你需要添加下面的代码来使新的类别属性正确安装:

      <resources>
      	<new_attribute_csv_setup>
      	  <setup>
      		<module>New_Attribute</module>
      		<class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
      	  </setup>
      	  <connection>
      		<use>core_setup</use>
      	  </connection>
      	</new_attribute_setup>
      	<new_attribute_setup_write>
      	  <connection>
      		<use>core_write</use>
      	  </connection>
      	</new_attribute_setup_write>
      	<new_attribute_setup_read>
      	  <connection>
      		<use>core_read</use>
      	  </connection>
      	</new_attribute_setup_read>
      </resources>
      

      注意,这里的类标签必须是 “Mage_Catalog_Model_Resource_Eav_Mysql4_Setup”

      正确安装后,进入后台类别中,你可以看到在General Information中出现了"New Category Attribute"。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 19 Oct 2015 12:43:03 +0000
      <![CDATA[分层导航]]> https://www.360magento.com/blog/magento-layered-navigation/ 最近,有个客户想要让所有“筛选器”一直显示。例如,当你想要通过颜色筛选器筛选产品时,发现所有的筛选器都在,那么你就可以轻松地按其它条件筛选而不必返回类别页。

      分层导航的文件默认在app/design/frontend/base/default/template/catalog/layer/下。分层导航的模版文件是view.phtml,用来显示筛选器。筛选器状态模版是state.phtml,当我们点击一个筛选器时,他响应结果。我们就要编辑state.phtml。将这个文件拷贝到你的包或主题中。

      这是默认的state.phtml文件:

      <?php $_filters = $this->getActiveFilters() ?>
      <?php if(!empty($_filters)): ?>
      <div class="currently">
          <p class="block-subtitle"><?php echo $this->__('Currently Shopping by:') ?></p>
          <ol>
          <?php foreach ($_filters as $_filter): ?>
              <li>
                  <a href="<?php echo $_filter->getRemoveUrl() ?>" title="<?php echo $this->__('Remove This Item') ?>" class="btn-remove"><?php echo $this->__('Remove This Item') ?></a>
                  <span class="label"><?php echo $this->__($_filter->getName()) ?>:</span> <?php echo $this->stripTags($_filter->getLabel()) ?>
              </li>
          <?php endforeach; ?>
          </ol>
          <div class="actions"><a href="<?php echo $this->getClearUrl() ?>"><?php echo $this->__('Clear All') ?></a></div>
      </div>
      <?php endif; ?>
      

      我们将要在“currently”div块前面添加当前类别的url通道。代码如下:

      <?php $obj = new Mage_Catalog_Block_Navigation(); ?>
      <?php $_current_category=$obj->getCurrentCategory()->getUrlPath(); ?> //getting url path of current category
      <?php $subs = $obj->getCurrentCategory()->getAllChildren(true); ?> //getting ids of subcategories of current category
      

      现在,我们编辑 “currently”div块。我将它重新命名为state。因为它不再显示当前筛选器。

      <?php if(!empty($_filters)): ?>
      <div class="state">
          <p class="block-subtitle"><?php echo $this->__('Currently Shopping by:') ?></p>
          <dl>
          <?php foreach ($_filters as $_filter): ?>
                  <dd>
                      <ol>
                          <?php $attributemodel=$_filter->filter->_data["attribute_model"]; ?>    // getting attribute model that has all filter options in it from currently active filter
                          <?php $attroptions=$attributemodel->getSource()->getAllOptions();?>   // getting attribute options (filters) from attribute model
                          <?php $_categ= Mage::getModel('catalog/category');?>   // object  containing all categories and their information
       
                      <?php foreach($subs as $cat_id): ?>
                              <?php $_categ->load($cat_id)?>           //get the subcategory you need
                              <?php $collection = $_categ->getProductCollection(); ?>  //get the product collection (object containing all product information)
                              <?php $collection->addAttributeToSelect('color')?>   // get the desired attribute
                      <?php endforeach; ?>
      

      接下来,我们需要提取属性模型的信息和组合链接。每一个属性选项 ($attroptions)都包含属性值和属性标签。

      <?php foreach($attroptions as $attr): ?>   // get value and label of each attribute
                              <?php $count=0; ?>
                              <?php if($attr["value"]!=""): ?>
                                     <?php $val=$attr["value"] ?>
                                      <?php $collection->addFieldToFilter(array(array('attribute'=>'themes','gt'=>10)))?>  // collection of attribute values and labels for all values
      
      //greater then 10 (in this case attribute values range was 18-39)
                                      <?php $proddata=$collection->getData() ?>  // get product data for all attribute values
                                      <?php if($attr["label"]!= $this->stripTags($_filter->getLabel())): ?>  // make a nice looking label
                                          <?php foreach($proddata as $prod):?>
                                              <?php if($prod["type_id"]=="configurable"): ?>    // in this store all products were configurable
                                                  <?php $split=split(",", $prod["color"]);?>     // get the attribute values that correspond with one product (a product may have more
      
      // then one attribute value and they're separated by commas that's why we split the string with "," as deliminator)
      

      即使你设置属性Filterable(with results) ,你仍然需要统计产品,这样只显示有产品的属性值。

       <?php foreach($split as $color): ?>  //check out how many products have the same attribute value
                                                      <?php if($color==$attr["value"]): ?>
                                                          <?php $count++;?>
                                                      <?php endif; ?>
                                                  <?php endforeach; ?>
       
                                              <?php endif;?>
       
                                          <?php endforeach; ?>
       
                                          <?php if($count>0):?>  // check if any product has that attribute value
                                              <li><a href="<?php echo $this->getUrl('').$_current_category ?>?color=<?php echo $attr["value"]?>" ><?php echo  $attr["label"]; ?></a></li>  // if not currently active filter make a link
                                          <?php endif; ?>
       
                                      <?php else:?>
                                          <li class="current"> <?php echo $this->stripTags($_filter->getLabel()); ?></li>  // if currently active filter write out the label
                                      <?php endif;?>
                              <?php endif; ?>
      <?php endforeach;  ?>
       
      <?php endforeach; ?> // ending the first for loop (foreach($filters as $filter))
                      </ol>
       
                  </dd>
          </dl>
          <a class="all" style="float:right;" href="<?php echo $this->getClearUrl()?>">All</a>    // show all products, return from current state back to category view
      </div>
      <?php endif; ?>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 18 Oct 2015 14:39:04 +0000
      <![CDATA[ 如何创建自定义属性源类型]]> https://www.360magento.com/blog/attribute-source-type/ 你是否曾经需要创建自定义属性源类型?下面的小示例可能会对你有所帮助。

      首先你需要创建sql安装文件,这个文件将把源类型的属性加入到你的系统中。源类型定义在数组: ‘source’ => ‘sourcetype/attribute_source_type’

      startSetup();
       
      $installer->addAttribute('catalog_product', 'product_type', array(
              'group'             => 'Product Options',
      		'label'             => 'Product Type',
      		'note'              => '',
              'type'              => 'int',	//backend_type
      		'input'             => 'select',	//frontend_input
      		'frontend_class'	=> '',
      		'source'			=> 'sourcetype/attribute_source_type',
              'backend'           => '',
              'frontend'          => '',
              'global'            => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE,
      		'required'          => true,
              'visible_on_front'  => false,
              'apply_to'          => 'simple',
              'is_configurable'   => false,
              'used_in_product_listing'	=> false,
              'sort_order'        => 5,
          ));
       
      $installer->endSetup();
      

      接着你需要创建自定义源类型或者名为Alwayly_Sourcetype_Model_Attribute_Source_Type的类,下面是我的例子:

      class Alwayly_Sourcetype_Model_Attribute_Source_Type extends Mage_Eav_Model_Entity_Attribute_Source_Abstract
      {
      	const MAIN = 1;
      	const OTHER = 2;
       
          public function getAllOptions()
          {
              if (is_null($this->_options)) {
                  $this->_options = array(
                      array(
                          'label' => Mage::helper('sourcetype')->__('Main Product'),
                          'value' =>  self::MAIN
                      ),
                      array(
                          'label' => Mage::helper('sourcetype')->__('Other Product'),
                          'value' =>  self::OTHER
                      ),
                  );
              }
              return $this->_options;
          }
       
          public function toOptionArray()
          {
              return $this->getAllOptions();
          }
       
          public function addValueSortToCollection($collection, $dir = 'asc')
          {
              $adminStore  = Mage_Core_Model_App::ADMIN_STORE_ID;
              $valueTable1 = $this->getAttribute()->getAttributeCode() . '_t1';
              $valueTable2 = $this->getAttribute()->getAttributeCode() . '_t2';
       
              $collection->getSelect()->joinLeft(
                  array($valueTable1 => $this->getAttribute()->getBackend()->getTable()),
                  "`e`.`entity_id`=`{$valueTable1}`.`entity_id`"
                  . " AND `{$valueTable1}`.`attribute_id`='{$this->getAttribute()->getId()}'"
                  . " AND `{$valueTable1}`.`store_id`='{$adminStore}'",
                  array()
              );
       
              if ($collection->getStoreId() != $adminStore) {
                  $collection->getSelect()->joinLeft(
                      array($valueTable2 => $this->getAttribute()->getBackend()->getTable()),
                      "`e`.`entity_id`=`{$valueTable2}`.`entity_id`"
                      . " AND `{$valueTable2}`.`attribute_id`='{$this->getAttribute()->getId()}'"
                      . " AND `{$valueTable2}`.`store_id`='{$collection->getStoreId()}'",
                      array()
                  );
                  $valueExpr = new Zend_Db_Expr("IF(`{$valueTable2}`.`value_id`>0, `{$valueTable2}`.`value`, `{$valueTable1}`.`value`)");
       
              } else {
                  $valueExpr = new Zend_Db_Expr("`{$valueTable1}`.`value`");
              }
       
       
       
              $collection->getSelect()
                  ->order($valueExpr, $dir);
       
              return $this;
          }
       
          public function getFlatColums()
          {
              $columns = array(
                  $this->getAttribute()->getAttributeCode() => array(
                      'type'      => 'int',
                      'unsigned'  => false,
                      'is_null'   => true,
                      'default'   => null,
                      'extra'     => null
                  )
              );
              return $columns;
          }
       
       
          public function getFlatUpdateSelect($store)
          {
              return Mage::getResourceModel('eav/entity_attribute')
                  ->getFlatUpdateSelect($this->getAttribute(), $store);
          }
      }
      

      如果安装正确地完成,进入Magento后台admin -> Catalog -> Product,你会看到一个名为“Product Options”的选项。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 18 Oct 2015 14:18:42 +0000
      <![CDATA[Magento中“Google +1”插件]]> https://www.360magento.com/blog/magento-google-1/ 嵌入谷歌+1按钮很简单,你所要做的就是在你的网页里加两段代码。一个在网页的头部,还有一个在你想要呈现的地方。你需要按照Google官方的指引来做:http://www.google.com/intl/en/webmasters/+1/button/index.html

      我们把插件的名字定为“GPlusOne”,在“Alwayly”命名空间里。让我们用下面的代码创建/app/etc/modules/Alwayly_GPlusOne.xml

      <?xml version="1.0"?>
       
      <config>
          <modules>
              <Alwayly_GPlusOne>
                  <active>true</active>
                  <codePool>community</codePool>
              </Alwayly_GPlusOne>
          </modules>
      </config>
      

      接着,用下面的代码创建我们的第二个文件app/code/community/Alwayly/GPlusOne/etc/config.xml

      <?xml version="1.0"?>
       
      <config>
          <modules>
              <Alwayly_GPlusOne>
                  <version>1.0.0.0</version>
              </Alwayly_GPlusOne>
          </modules>
          <global>
              <blocks>
                  <alwayly_gplusone>
                      <class>Alwayly_GPlusOne_Block</class>
                  </alwayly_gplusone>
              </blocks>      
          </global>
       
          <frontend>
              <layout>
                  <updates>
                      <alwayly_gplusone>
                          <file>alwayly/gplusone.xml</file>
                      </alwayly_gplusone>
                  </updates>
              </layout>        
          </frontend>
      </config>
      

      如你所见,我们声明了gplusone.xml这个布局文件,app/design/frontend/default/default/layout/alwayly/gplusone.xml的代码:

      <?xml version="1.0"?>
       
      <layout version="1.0.0">
          <catalog_product_view>
              <reference name="head">
                  <block type="core/template" name="alwayly_gplusone_head" template="alwayly/gplusone_head.phtml" />
              </reference>        
              <reference name="alert.urls">
                  <block type="alwayly_gplusone/PlusButton" name="alwayly_gplusone" />
              </reference>
          </catalog_product_view>
      </layout>
      

      仔细观察,你会发现gplusone.xml更新产品详细页。由于嵌入谷歌+1按钮需要在页面读取两个脚本,我们就将它们分别放到下面两个文件中:

      app/design/frontend/default/default/template/alwayly/gplusone_head.phtml

      app/design/frontend/default/default/template/alwayly/gplusone_button.phtml

      app/design/frontend/default/default/template/alwayly/gplusone_head.phtml文件通过‘reference name=”head”‘来更新布局,代码如下:

      <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
      

      app/design/frontend/default/default/template/alwayly/gplusone_button.phtml通过‘reference name=”alert.urls”'载入到页面的alert.urls块中。gplusone_button.phtml的代码如下:

      <code<<g:plusone <?php if($size = $this->getSize()) { echo ' size="'.$size.'"'; } ?>></g:plusone>
      

      最后,用下面的代码创建app/code/community/Alwayly/GPlusOne/Block/PlusButton.php

      <?php
       
      class Alwayly_GPlusOne_Block_PlusButton extends Mage_Core_Block_Template
      {
          /**
           * Constructor. Set template.
           */
          protected function _construct()
          {
              parent::_construct();
              $this->setTemplate('inchoo/gplusone_button.phtml');
          }
       
          public function getSize() 
          {
              //Here we can implement the code to read the config values for sizes
              return '';
          }
      }
      

      如果你观察gplusone_button.phtml文件,你会发现它调用Alwayly_GPlusOne_Block_PlusButton类里的getSize()方法。目前,这个方法没有什么作用,是为了以后扩展用的。鉴于谷歌+1按钮支持多钟尺寸(小,中等,高以及标准大小),你可以在插件里添加些简单的逻辑来获取Magento后台中输入的值。

      本文不是给你一个不成熟的插件,而是向你展示以Magento的方式实现一个简单的谷歌+插件需要哪些东西。(这不一样是最好的方法)

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 17 Oct 2015 10:16:29 +0000
      <![CDATA[获取Magento中属性的值,名字和其它信息]]> https://www.360magento.com/blog/magento-attribute-info/ 产品的属性是一个非常重要的功能,我们经常会用到。在这篇文章中我将总结的一些产品属性信息的输出方法跟大家分享一下。

      1、获取属性集合

      $attribute = $_product->getResource()->getAttribute(‘attribute_code’); 

      2、获取属性类型

      $attribute->getAttributeType(); 

      3、获取属性Label

       $attribute->getFrontendLabel(); 

      4、获取属性默认值

      $attribute->getDefaultValue(); 

      5、获取属性设置值

      $attribute->getFrontend()->getValue($_product); 

      6、检查属性是否可见

      $attribute->getIsVisible(); 

      7、检查属性是否是必填项

      $attribute->getIsRequired();

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 17 Oct 2015 10:05:02 +0000
      <![CDATA[如何禁用Magento事件]]> https://www.360magento.com/blog/disable-magento-event/ 有些情况下你希望禁用Magento事件。例如,在一个我们的项目中,我们决定禁用所有的“Mage_Log”事件来减少数据库的sql查询。我们将在这篇文章中描述我们是怎么做的,但我相信这个方法可以在很多场景中应用。

      Magento事件是怎么定义的呢?例如,你到Magento模型“Mage_Log”config.xml文件中,你会发现下一个内容在“events”标签里。

      “Events”标签包含子事件,你可以看config.xml文件中的块。

      <frontend>
      	<events>
                  <controller_action_predispatch>
                      <observers>
                          <log>
                              <class>log/visitor</class>
                              <method>initByRequest</method>
                          </log>
                      </observers>
                  </controller_action_predispatch>
                  .... other events
              </events>
      </frontend>
      

      例如,如果你想要禁用 “controller_action_predispatch” 事件,你需要创建自己的模型并将它放到你的config.xml文件中。

      <frontend>
      	<events>
      		<controller_action_predispatch>
      			<observers><log><type>disabled</type></log></observers>
      		</controller_action_predispatch>
      	</events>
      </frontend>
      

      也许你注意到了,我们添加值为“disable“的“type”标签。进入Magento类 “Mage_Core_Model_App” ,在“dispatchEvent”方法中,你将看到:

       foreach ($events[$eventName]['observers'] as $obsName=>$obs) {
                      $observer->setData(array('event'=>$event));
                      Varien_Profiler::start('OBSERVER: '.$obsName);
                      switch ($obs['type']) {
                          case 'disabled': // if we set disabled type, event will not be executed.
                              break;
                          case 'object': case 'model':
                              $method = $obs['method'];
                              $observer->addData($args);
                              $object = Mage::getModel($obs['model']);
                              $this->_callObserverMethod($object, $method, $observer);
                              break;
                          default:
                              $method = $obs['method'];
                              $observer->addData($args);
                              $object = Mage::getSingleton($obs['model']);
                              $this->_callObserverMethod($object, $method, $observer);
                              break;
                      }
                      Varien_Profiler::stop('OBSERVER: '.$obsName);
                  }
      

      如果设置事件type为“disabled”,事件将不会被执行。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 16 Oct 2015 12:15:13 +0000
      <![CDATA[编辑Magento中的PDF地址]]> https://www.360magento.com/blog/edit-pdf-address/ 在Magento中编辑PDF是受限制的,但是如果你需要编辑的只是一个地址,你可以使用事件。

      首先在config.xml中设置你的观测者:

      <adminhtml>
          	<events>
          	    <customer_address_format>
          		<observers>
                          <alwayly_sales_customer_address_format_observer>
                              <type>model</type>
                              <class>alwayly_sales/observer</class>
                              <method>addAdditionalDataToAddress</method>
                          </alwayly_sales_customer_address_format_observer>
                      </observers>
          	    </customer_address_format>
          	</events>
      </adminhtml>
      

      在设置完观测者之后,你需要写代码来编辑地址模版:

      /**
       * Observer printing invoices in PDF
       *
       * @category    Alwayly
       * @package     Alwayly_Sales
       */
      class Alwayly_Sales_Model_Observer
      {
          public function addAdditionalDataToAddress(Varien_Event_Observer $address)
          {
          	$data = $address->getEvent();
          	if($data->type['code']=="pdf")
          	{
          		$customerData = $data["address"]->getOrder()->getData();
          		$customerId = $customerData['customer_id'];
          		//we are using customer object because it give us latest user data, if you want data from user on order creation use $customerData
      			$customer = Mage::getModel('customer/customer')->load($customerId);
      			$customerVariable = $customer->get?????;
       
      			//prevent of multiple insertion
          		if(strpos($data->type['default_format'],"Customer Variable")===false)
          		{
          		 	$stringToInsert = "{{var company}}|{{/depend}}|Customer Variable: ".$customerVariable."|";
          		 	$data->type['default_format'] = str_replace("{{var company}}|{{/depend}}",$stringToInsert, $data->type['default_format']);
          		};
          	};
          }
      }
      

      如果你想要获取最后一个用户的数据,你要使用Mage::getModel(‘customer/customer’) 对象。注意,用你自己的数据替换?????。我们获取地址模版并做修改。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 16 Oct 2015 12:05:36 +0000
      <![CDATA[在Magento中展示产品选项的HTML代码(块)]]> https://www.360magento.com/blog/product-options-html/ 这个简单的助手可以帮你显示产品选项的html代码。它适用于简单(simple), 虚拟(virtual)和可配置(configurable)产品。我相信你也可以将同样的方法应用到其它产品上。获取可配置产品选项的HTML代码会一点。

      对于简单产品,我们有一种非常“干净的方法”。

      首先,我们为产品设置一个块,接着我们添加物品渲染器(template和type)到产品选项块。最后一步就是创建迭代选择并与我们的产品选项块一起显示。

      我们可以看到一些不错的松耦合和代码分离。另一方面,获取可配置产品选项的html代码并不这么灵活。实例块,实例化产品。我们获取选项的html。

      抽样:

      echo Mage::helper("alwayly_checkout")->getProductOptionsHtml(Mage::getModel("catalog/product")->load(171));

      助手:

      <!--?php <br ?-->/**
       * @category    Alwayly
       * @package     Alwayly_Checkout
       * @author      Alwayly
       */
      class Alwayly_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
      {
      	/**
      	 * 
      	 * getting html for options of products
      	 * @param Mage_Catalog_Model_Product $product
      	 */
      	public function getProductOptionsHtml(Mage_Catalog_Model_Product $product)
      	{ 
      		$blockOption = Mage::app()->getLayout()->createBlock("Mage_Catalog_Block_Product_View_Options");
                      $blockOption->addOptionRenderer("default","catalog/product_view_options_type_default","catalog/product/view/options/type/default.phtml");
      		$blockOption->addOptionRenderer("text","catalog/product_view_options_type_text","alwayly_catalog/product/view/options/type/text.phtml");
      		$blockOption->addOptionRenderer("file","catalog/product_view_options_type_file","catalog/product/view/options/type/file.phtml");
      		$blockOption->addOptionRenderer("select","inchoo_checkout/product_view_options_type_select","catalog/product/view/options/type/select.phtml");
      		$blockOption->addOptionRenderer("date","catalog/product_view_options_type_date","catalog/product/view/options/type/date.phtml") ;
       
       
      		$blockOptionsHtml = null;
       
      		 if($product->getTypeId()=="simple"||$product->getTypeId()=="virtual"||$product->getTypeId()=="configurable")
      		 {  
      		 	$blockOption->setProduct($product);
      			if($product->getOptions())
      			{  
      				foreach ($product->getOptions() as $o) 
      	    		{     
      	    			$blockOptionsHtml .= $blockOption->getOptionHtml($o); 
      	    		};    
      			}  
      		 }  
       
      		 if($product->getTypeId()=="configurable")
      		 {   
      		 	$blockViewType = Mage::app()->getLayout()->createBlock("Mage_Catalog_Block_Product_View_Type_Configurable");
      		 	$blockViewType->setProduct($product);   
      		 	$blockViewType->setTemplate("inchoo_catalog/product/view/type/options/configurable.phtml");
      			$blockOptionsHtml .= $blockViewType->toHtml(); 
      		 }  
      		 return $blockOptionsHtml; 
      	}
      }
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 15 Oct 2015 09:50:04 +0000
      <![CDATA[删除Magento中的测试订单]]> https://www.360magento.com/blog/delete-magento-orders/ 当你开发一个Magento项目,你会创建一个Magento主题,放置初始产品和类别,还放置一些订单来测试送货方式和支付方法的正常运行。一切都很好,客户也想要看看网站。可是运行中,你将看到一些本应该删除的测试订单。

      当你想在后台删除订单的时候你会发现,你只能将订单状态改为“取消”,而订单仍然在那里。Magento不允许我们通过后台来删除这些,所以你看不到任何“删除订单”按钮。这对商家和开发人员来说都是让人沮丧的。来自SAP的人发现不能删除订单有些好处,但是应该有一个状态来从报告中消除销售、库存等信息的销售计数。

      那么,怎么做呢?

      你可以在你的Magento根目录下创建一个php脚本,粘贴下面的代码:

      <?php
      /**
      * @copyright Alwayly
      */
      
      if (version_compare(phpversion(), '5.2.0', '<')===true) {
      echo '<div style="font:12px/1.35em arial, helvetica, sans-serif;"><div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;"><h3 style="margin:0; font-size:1.7em; font-weight:normal; text-transform:none; text-align:left; color:#2f2f2f;">Whoops, it looks like you have an invalid PHP version.</h3></div><p>Magento supports PHP 5.2.0 or newer. <a href="http://www.magentocommerce.com/install" target="">Find out</a> how to install</a> Magento using PHP-CGI as a work-around.</p></div>';
      exit;
      }
      
      error_reporting(E_ALL | E_STRICT);
      ini_set('display_errors', 1);
      
      $mageFilename = 'app/Mage.php';
      
      if (!file_exists($mageFilename)) {
      echo $mageFilename." was not found";
      exit;
      }
      
      require_once $mageFilename;
      
      Mage::app();
      
      $executionPath = null;
      
      /*
      * determine Magento Edition
      */
      if (file_exists('LICENSE_EE.txt')) {
      $edition = 'EE';
      }elseif (file_exists('LICENSE_PRO.html')) {
      $edition = 'PE';
      } else {
      $edition = 'CE'; 
      }
      
      if(($edition=='EE' && version_compare(Mage::getVersion(), '1.11.0.0.', '<')===true)
      || ($edition=='PE' && version_compare(Mage::getVersion(), '1.11.0.0.', '<')===true)
      || ($edition=='CE' && version_compare(Mage::getVersion(), '1.6.0.0.', '<')===true)
      ){
      $executionPath = 'old'; 
      } else {
      $executionPath = 'new'; 
      }
      
      $xpathEntity = 'global/models/sales_entity/entities//table';
      
      if ($executionPath == 'old') {
      $xpathResource = 'global/models/sales_mysql4/entities//table';
      } else {
      $xpathResource = 'global/models/sales_resource/entities//table';
      }
      
      $salesEntitiesConf = array_merge(
      Mage::getSingleton('core/config')->init()->getXpath($xpathEntity), 
      Mage::getSingleton('core/config')->init()->getXpath($xpathResource)
      );
      
      $resource = Mage::getSingleton('core/resource');
      $connection = $resource->getConnection('core_write');
      
      
      /*
      * If you want delete System/Order Statuses (Status and State) you
      * should comments below lines (46-51)
      */
      $skipTables = array (
      $resource->getTableName('sales_order_status'),
      $resource->getTableName('sales_order_status_state'),
      $resource->getTableName('sales_order_status_label')
      );
      $salesEntitiesConf = array_diff($salesEntitiesConf, $skipTables);
      
      
      /*
      
      Multiple RDBMS Support in Magento CE 1.6+ / EE 1.11+
      http://www.magentocommerce.com/images/uploads/RDBMS_Guide2.pdf
      
      2.2. Adapters:
      
      ... The new Varien_DB_Adapter_Interface was added to sign a contract that all 
      developed adapters must execute in order to get Magento working on an actual 
      database. The interface describes the list of methods and constants that can be used by resource models...
      
      Used below in the loop:
      
      * If $executionPath == 'old'
      * Varien_Db_Adapter_Pdo_Mysql::showTableStatus()
      * Varien_Db_Adapter_Pdo_Mysql::truncate() 
      * Else
      * Varien_Db_Adapter_Interface::isTableExists()
      * Varien_Db_Adapter_Interface::truncateTable()
      
      */
      
      while ($table = current($salesEntitiesConf) ){
      $table = $resource->getTableName($table);
      
      if ($executionPath == 'old') {
      $isTableExists = $connection->showTableStatus($table);
      } else {
      $isTableExists = $connection->isTableExists($table);
      }
      if ($isTableExists) {
      try {
      if ($executionPath == 'old') {
      $connection->truncate($table);
      } else {
      $connection->truncateTable($table);
      }
      
      printf('Successfully truncated the <i style="color:green;">%s</i> table.<br />', $table);
      } catch(Exception $e) {
      printf('Error <i style="color:red;">%s</i> occurred truncating the <i style="color:red;">%s</i> table.<br />', $e->getMessage(), $table);
      }
      }
      
      next($salesEntitiesConf);
      }
      
      exit('All done...');
      

      代码执行后,数据库里再也不会有测试订单了。记住,这将删除所有数据库中订单。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 15 Oct 2015 09:45:36 +0000
      <![CDATA[用自定义输入渲染器添加Magento属性]]> https://www.360magento.com/blog/attribute-input-renderer/ 这个例子将给你解释如何用自定义输入渲染添加新属性。你将修改已有的功能,添加JavaScript,一些其它的选项或者改变默认的输入渲染。

      你可能会问什么是Magento输入渲染器。这是一个负责呈现HTML表单元素的Magento php类。在Magento里有不同的渲染类,你可以在/lib/Varien/Data/Form/Element的文件夹里找到它们。

      让我们开始我们的示例吧。

      首先创建Magento安装文件,下面是示例:

      <?php
      $installer = $this;
       
      $installer->startSetup();
       
      $installer->addAttribute(Mage_Catalog_Model_Product::ENTITY, 'example_field', array(
          'group'             => 'General',
          'type'              => 'text',
          'backend'           => '',
          'input_renderer'    => 'test/catalog_product_helper_form_example',//definition of renderer
          'label'             => 'Example field',
          'class'             => '',
          'global'            => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE,
          'visible'           => true,
          'required'          => false,
          'user_defined'      => true,
          'searchable'        => false,
          'filterable'        => false,
          'comparable'        => false,
          'visible_on_front'  => false,
          'unique'            => false,
          'apply_to'          => 'simple,configurable,bundle,grouped',
          'is_configurable'   => false,
      ));
       
      $installer->endSetup();
      

      你可以看到,我们用“addAttribute”方法来添加属性,变量“$installer”是“Mage_Catalog_Model_Resource_Setup&rdquo;的实例,前端输入渲染定义在数组 ‘input_renderer’ => ‘test/catalog_product_helper_form_example’

      下一步,你需要创建自己的输入渲染器。下面是我的例子(Alwayly_Test_Block_Catalog_Product_Helper_Form_Price),一个简单的类,为了用来演示。

      <?php
      class Alwayly_Test_Block_Catalog_Product_Helper_Form_Example extends Varien_Data_Form_Element_Text
      {
          public function getAfterElementHtml()
          {
              $html = parent::getAfterElementHtml();
              return $html."
      
      "; } 
      }

      在我的例子里,我添加java代码来禁用输入元素,管理员用户无法编辑此字段。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 14 Oct 2015 11:15:53 +0000
      <![CDATA[来自Magento的苹果推送通知]]> https://www.360magento.com/blog/apple-push-notifications/ 不是每个人都对这个标题很熟悉,苹果推送通知服务(APNS)是苹果公司为其移动设备(iPhone, iPad …) 提供的基础服务,可以给特定的监听应用发送特定的信息。

      对于APNS的正确用法,他们可能需要集成到移动应用程序里,也需要苹果移动层面上发送信息的证书。

      我不是一个IOS开发人员,所以我没有资格去写这个故事的移动端,但是,这里还有另一个方面需要被覆盖。我会尽量解释如何利用Magento来发送推送信息到目标移动设备。

      使用Magento时思路可以是多样的:当新订单被创建或者客户注册我们可以发推送信息,或者我们可以用在Magento移动端来发送类似通讯的消息……

      这篇教程假设你已经参加了苹果开发计划,注册了APNS并集成APNS功能到你的移动应用。

      为了在Magento中使用APNS我先要做点准备工作。

      从源代码中准备可用的APNS证书

      登录到你的苹果开发者网站,下载APNS使用证书。将证书拷贝到你插件文件系统中的,另外记得写下证书的密码。

      在数据库中创建自定义的表单来存储独特的标记和其它APNS需要的参数

      在我们的APNS表中,我们将为每一个接收推送信息的设备保存独特的标记。这个设备的标记可能是应用启动时移动设备发出的。为了在数据库保存device_token。我们需要创建独立的Magento web服务方法,当移动应用启动时被调用。

      我们需要从移动应用发送APNS设备标记到apns_save Web服务方法。在web服务方法中我们应该要对设备标记添加/更新来避免重复。

      下面是一个web服务API方法的示例:

      <!--?php <br ?-->
      /*
       * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
       */
       
      class Alwayly_Mapy_Model_Core_Apns_Api_V2 extends Mage_Api_Model_Resource_Abstract {
       
          public function setParams($token, $events, $appversion, $period) {
       
              $api_user = Mage::getSingleton('api/session')->getUser();
              $userExists = ($api_user && $api_user->getId()) ? true : false;
       
              if (!$userExists) {
                  $this->_fault('not_exists', 'User does not exist!');
              }
              if (!$token) {
                  $this->_fault('data_invalid', 'Device token not set!');
              }
              if ($token == '') {
                  $this->_fault('data_invalid', 'Device token invalid!');
              }
       
              $collection = Mage::getSingleton('inchoo_mapy/core_apns')->getCollection();
       
              $collection->addFieldToFilter('user_id', $api_user->getId());
              $collection->addFieldToFilter('device_token', $token);
       
              $app = explode('-', $appversion);
              if (count($app) > 0) {
                  $collection->addFieldToFilter('app_version',array('like'=>$app[0] . '%'));
              } else {
                  $this->_fault('data_invalid', 'App version not supported!');
              }
              $param = $collection->getFirstItem();
       
              $currentTime = now();
       
              if ($period < 60) {             $period = 60;         }         $sess_id = Mage::getSingleton('api/session')-
      
      >getSessionId();
       
              $param->setUserId($api_user->getId());
              $param->setAppVersion($appversion);
              $param->setDeviceToken($token);
              $param->setEvents($events);
              $param->setStatus('active');
              $param->setNotificationPeriod($period);
              $param->setUpdatedAt($currentTime);
              $param->setLastSession($sess_id);
       
              $param->save();
       
              return true;
          }
      

      创建用于发送推送信息的助手

      当我们存储设备标记到我们的表里时,我们决定从Magento中何时,发送什么,发送给哪些设备信息的逻辑。当然,也要实现发送-间隔的逻辑来避免垃圾信息。

      <!--?php <br ?-->
      /*
       * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
       */
       
      class Alwayly_Mapy_Helper_ApnsLite extends Mage_Core_Helper_Abstract {
       
          const CONFIG_XML_PATH_APPLE_SSL = 'inchoo_mapy/settings/apnsssl';
          const CONFIG_XML_PATH_APPLE_FEEDBACK = 'inchoo_mapy/settings/apnsfeedback';
       
          private function _getCertificate() {
              return Mage::getBaseDir() . DS . 'app' . DS . 'code' . DS . 'community' . DS .
                      'Inchoo' . DS . 'Mapy' . DS . 'lib' . DS . 'apple' .
                      DS . 'certificate' . DS . 'ck_production_lite.pem';
          }
       
          public function sendPushNotifications() {
       
              $certificate = $this->_getCertificate();
              $devices = $this->_getDevicesForNotification();
       
              $messages = array();
              foreach ($devices as $device) {
       
                  if ($device['received_at'] == null) {
                      $now = Zend_Date::now();
                      $now->sub(1, Zend_Date::HOUR);
       
                      $from_time = $now;
                  } else {
                      $from_time = new Zend_Date($device['received_at'], Varien_Date::DATETIME_INTERNAL_FORMAT);
                  }
       
                  $data = array();
                  if (strpos($device['events'], 'new_orders') !== false) {
                      $result = $this->_getNewOrders($from_time);
                      $data['orders_sum'] = $result['sales_total'];
                      $data['orders_count'] = $result['num_orders'];
                  }
                  if (strpos($device['events'], 'new_customers') !== false) {
                      $result = $this->_getNewCustomers($from_time);
                      $data['customers_count'] = $result['new_customers'];
                  }
       
                  $message = $this->_prepareMessage($data);
       
                  if (md5($message) == $device['last_msg_hash']) {
                      $message = null;
                  }
       
                  $sess_id = $device['last_session'];
                  $session = Mage::getSingleton('api/session');
       
                  $user = Mage::getModel('api/user')->loadBySessId($sess_id);
       
                  $user = Mage::getModel('api/user')->loadBySessId($sess_id);
                  if ((!$session->isLoggedIn($sess_id))||(!$user->hasUserId())) {
                      $message = null;
                      $collection = Mage::getModel('inchoo_mapy/core_apns')->getCollection();
                      $collection->addFieldToFilter('last_session', $sess_id);
       
                      foreach ($collection as $val) {
                          if ($val->getId()) {
                              $val->setStatus('inactive');
                              $val->save();
                          }
                      }
                  }
       
                  if ($message != null) {
                      $messages[] = array(
                          'msg' => $message,
                          'device' => $device['device_token'],
                      );
                  }
              }
       
              if (count($messages) > 0) {
                  $this->_pushMessage($messages, $certificate);
              }
          }
       
          private function _prepareMessage($data) {
       
              $helper = Mage::helper('inchoo_mapy');
       
              $message = '';
              $badge = 0;
              $mage_events = array();
       
              if (isset($data['orders_sum'])) {
                  if ($data['orders_sum'] > 0) {
                      $message.='Sales total: ' . $helper->currencyToBaseFormat($data['orders_sum']);
                  }
              }
       
              if (isset($data['orders_count'])) {
                  if ($data['orders_count'] > 0) {
                      $message.=' Orders count: ' . $data['orders_count'];
                      $badge+=$data['orders_count'];
                      $mage_events[] = array('mage_event' => 'new_orders', 'count' => $data['orders_count']);
                  }
              }
       
              if (isset($data['customers_count'])) {
                  if ($data['customers_count'] > 0) {
                      $message.=' New customers count: ' . $data['customers_count'];
                      $badge+=$data['customers_count'];
                      $mage_events[] = array('mage_event' => 'new_customers', 'count' => $data['customers_count']);
                  }
              }
       
              if ($badge == 0) {
                  return;
              }
       
              $body['aps'] = array(
                  'sound' => 'tick.caf',
                  'alert' => $message,
                  'badge' => (int) $badge,
                  'mage-events' => $mage_events
              );
       
              $payload = json_encode($body);
       
              return $payload;
          }
       
          private function _getDevicesForNotification() {
       
              $collection = Mage::getModel('inchoo_mapy/core_apns')->getCollection();
              $collection->addFieldToFilter('status', 'active');
       
              $where_expr = 'DATE_ADD(IFNULL(sent_at, DATE_SUB(UTC_TIMESTAMP(), INTERVAL 3600 SECOND )),INTERVAL notification_period 
      
      SECOND)                 $param->save();
                  }
              }
          }
       
      }
      

      如果你阅读了代码,你会发现我们有些公用的方法来发送通知。这些方法里我们先读取设备,然后我们再读取个准备信息的数据并在条件满足时发送它们。

      • _prepareMessage方法是用来将数据加入到合适的json信息格式
      • _pushMessage是信息发送方法
      • _checkFeedback用来列出关闭推送信息的苹果设备,我们需要在表中把它们标记为inactive。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 14 Oct 2015 11:07:54 +0000
      <![CDATA[注入变量到Magento CMS静态块]]> https://www.360magento.com/blog/injecting-variables-static/ 在这篇教程中我将演示如何注入你需要的自定义变量到一个cms静态块,使用{{var variable_name}}标签。如果你正在处理email模版,那么你会看到这个。(本质是我们使用和email模版同样的用来注入变量的筛选器。

      首先,让我们假设几件事情:

        包命名为'Company',模块命名为'Module'
      1. 你知道如何创建一个php模型和新的块类。例子中的块别名是‘module/dynamic’
      2. 动态块的模版是dynamic.phtml
      3. 静态cms块的id是‘static_block’(你需要在后台创建它)
      4. 你需要添加当前用户的email到静态块。什么时候显示模块和文本范围的逻辑。

      第一步,我们看下模版文件,里面只使用我们想要创建块类的方法:

      <?php if(Mage::getSingleton('customer/session')->getCustomer()->getId()) : ?>
      	<?php echo $this->getStaticBlock();?>
      <?php endif;?>
      

      如你所见,我们只检查客户是否存在。下面我们看动态块类里的逻辑:

      <?php
      /**
       * Just another block class
       */
      class Company_Module_Block_Dynamic extends Mage_Core_Block_Template
      {
      	/**
      	 * This getter will return the html of your static block
      	 * @return string
      	 */
      	public function getStaticBlock()
      	{
      		// loading the static block
      		$block = Mage::getModel('cms/block')
      		->setStoreId(Mage::app()->getStore()->getId())
      		->load('static_block');
      		/* @var $block Mage_Cms_Model_Block */
       
      		// setting the assoc. array we send to the filter.
      		$array = array();
      		// the array keys are named after the tags in the static block. let's say $array['customer_email'] is {{var customer_email}} in the static block. you can set as many variables you need.
      		$array['customer_email'] = Mage::getSingleton('customer/session')->getCustomer()->getEmail();
       
      		// loading the filter which will get the array we created and parse the block content
      		$filter = Mage::getModel('cms/template_filter');
      		/* @var $filter Mage_Cms_Model_Template_Filter */
      		$filter->setVariables($array);
       
      		// return the filtered block content.
      		return $filter->filter($block->getContent());
       
      	}
      }
      ?>
      

      现在,在你CMS中的static_block块中添加 {{var customer_email}}标签,它将被动态地添加到CMS块。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 13 Oct 2015 10:53:29 +0000
      <![CDATA[使用xpath和varien_object运行模块xml文件中指定的方法]]> https://www.360magento.com/blog/xpath-varien_object/ 去年,我们为用户开发了一些定制的EPR系统。客户的文件中指出他们需要运行一些在config.xml中定义的方法,在出口订单的时候用方法代码作为ID。很快,根据订单的付款代码他们想在出口订单时添加一些自定义计算。如果你对我们如何实现的感兴趣,那么继续阅读吧。

      举例会让解释变得简单。首先创建我们的config.xml,最后我们将让Magento呼应我们的模块。

      Step 1: Creating module’s configuration(创建模型配置)

      这里只是个简单的示例代码,你可以用它创建app/code/local/Alwayly/XmlMethodCall/etc/config.xml

      < ?xml version="1.0"?>
       
      <config>
       
          <modules>
             <alwayly_xmlmethodcall>
                 <version>1.0.0.0</version>
             </alwayly_xmlmethodcall>
          </modules>
       
          <global>
             <xml_method_call>
                 <payment_checkmo>
                     <name>Check / Money order </name>
                     <code>checkmo</code>
                     <add>
                         <model>alwayly_xmlmethodcall/checkmoAddVal</model>
                         <method>addValue</method>
                     </add>
                     <return>
                         <model>alwayly_xmlmethodcall/checkmoGetCod</model>
                         <method>getCode</method>
                     </return>
                 </payment_checkmo>
             </xml_method_call>
             <xml_method_call>
                 <payment_ccsave>
                     <name>Credit Card (saved) </name>
                     <code>ccsave</code>
                     <add>
                         <model>alwayly_xmlmethodcall/ccsaveAddVal</model>
                         <method>addValue</method>
                     </add>
                     <return>
                         <model>alwayly_xmlmethodcall/ccsaveGetCod</model>
                         <method>getCode</method>
                     </return>
                 </payment_ccsave>
             </xml_method_call>
             <models>
                 <alwayly_xmlmethodcall>
                     <class>Alwayly_XmlMethodCall_Model</class>
                     <resourcemodel>alwayly_xmlmethodcall_mysql4</resourcemodel>
                 </alwayly_xmlmethodcall>
             </models>
          </global>
       
          <frontend>
             <routers>
                 <alwayly_xmlmethodcall>
                     <use>standard</use>
                     <args>
                         <module>Alwayly_XmlMethodCall</module>
                         <frontname>xmlmethodcall</frontname>
                     </args>
                 </alwayly_xmlmethodcall>
             </routers>
          </frontend>
       
      </config>
      

      深入研究下xml_method_call结点和全球结点的第一子节点。你会看到两兄弟有同样的名字, xml_method_call结点。

      让我们描述下下一个xml块:

      <payment_checkmo>
          <name>Check / Money order </name>
          <code>checkmo</code>
          <add>
              <model>alwayly_xmlmethodcall/checkmoAddVal</model>
              <method>addValue</method>
          </add>
          <return>
              <model>alwayly_xmlmethodcall/checkmoGetCod</model>
              <method>getCode</method>
          </return>
      </payment_checkmo>
      
      • payment_checkmo 包含一些数据的唯一结点
      • name 这个唯一结点的名字,与代码无关
      • code 支付方式的代码(id)
      • add,return 两种方法定义他们应该调用的东西(模块/模型和方法调用的定义)

      现在我希望你对我们需要怎么实现有一个清晰的认识。在订单出口的时候我们调用一些方法做计算并返回结果。要求是方法需要是可配置的,这样非开发人员可以通过配置文件来改变它们。当然,你可以在system.xml中做到这点。

      Step 2: Creating module’s models, described in config.xml(创建模块的模型,在config.xml中写描述)

      Create files:

      • – app/code/local/Alwayly/XmlMethodCall/Model/CheckmoAddVal.php
      • – app/code/local/Alwayly/XmlMethodCall/Model/CheckmoGetCod.php
      • – app/code/local/Alwayly/XmlMethodCall/Model/CcsaveAddVal.php
      • – app/code/local/Alwayly/XmlMethodCall/Model/CcsaveGetCod.php

      分别添加下面的代码到对应的文件中:

      < ?php
       
      /**
      *
      */
      class Alwayly_XmlMethodCall_Model_CheckmoAddVal extends Mage_Core_Model_Abstract
      {
       
         public function addValue()
         {
             return 1;
         }
      }
      
      < ?php
       
      /**
      *
      */
      class Alwayly_XmlMethodCall_Model_CheckmoGetCod extends Mage_Core_Model_Abstract
      {
       
         public function getCode()
         {
             return 'a';
         }
      }
      
      < ?php
       
      /**
      */
      class Alwayly_XmlMethodCall_Model_CcsaveAddVal extends Mage_Core_Model_Abstract
      {
       
         public function addValue()
         {
             return 2;
         }
      }
      
      < ?php
       
      /**
      *
      */
      class Alwayly_XmlMethodCall_Model_CcsaveGetCod extends Mage_Core_Model_Abstract
      {
       
         public function getCode()
         {
             return 'b';
         }
      }
      

      因为是一个简单的教学示例,我们将只创建控制器并在里面的几个列数组里的订单。

      Step 3: Creating controller(创建控制器)

      < ?php
       
      /**
      *
      */
      class Alwayly_XmlMethodCall_IndexController extends Mage_Core_Controller_Front_Action
      {
       
         public function indexAction()
         {
             $orders = array();
             $orders[] = array (
                 'order_no'    => 101,
                 'method'    => 'checkmo',
                 'amount'    => 99
             );
             $orders[] = array (
                     'order_no'    => 102,
                     'method'    => 'ccsave',
                     'amount'    => 100
             );
             $orders[] = array (
                     'order_no'    => 101,
                     'method'    => 'checkmo',
                     'amount'    => 199
             );
       
             foreach ($orders as $row) {
                 $orderNo = $row['order_no'];
                 $conf = Mage::getSingleton('core/config')->init()
                     ->getXpath('global/xml_method_call//code[.="' . $row['method'] . '"]/..');
       
                 if ($conf) {
                     $conf = new Varien_Object(current($conf)->asArray());
                     $add = new Varien_Object($conf->getAdd());
                     $code = new Varien_Object($conf->getReturn());
       
                     if (method_exists(Mage::getModel($add->getModel()), $add->getMethod())) {
                         $amountValue = $row['amount'] + Mage::getModel($add->getModel())->{$add->getMethod()}();
                     }
                     if (method_exists(Mage::getModel($code->getModel()), $code->getMethod())) {
                         $codeValue = Mage::getModel($code->getModel())->{$code->getMethod()}();
                     }
                 } else {
                     //throw an error
                     die("or exit... or something goes wrong...");
                 }
                 echo "<pre>"                     . PHP_EOL;
                 echo 'ID: '     . $orderNo         . PHP_EOL;
                 echo 'VALUE: '     . $amountValue     . PHP_EOL;
                 echo 'CODE: '     . $codeValue     . PHP_EOL;
             }
             print_r($orders);
         }
      }
      

      首先,我们创建了包含一些$orders里数据的订单集合。这可能是一个真实的集合,但是现在为了简化,我决定用个简单的二维数组。

      下一个重要的部分是:

      $conf = Mage::getSingleton('core/config')->init()->getXpath('global/xml_method_call//code[.="' . $row['method'] . '"]/..');
      

      如你所见,我们调用code/config模型里的XPath。如果你不知道this ->getXpath(‘global/xml_method_call//code[.=”‘ . $row[‘method’] . ‘”]/..’)的意思,那么你可以去w3schools/XPath学些新东西。

      我们将要实例化$conf对象,把xml_method_call作为根节点。我们不知道哪一个是它,但我们知道方法的代码并可以在config.xml搜索它。

      "//"意味着同一级别。比temp结点深,确认你所能找到的所有结点然后挑选出含有你所需值的那个。

      "/.."意味着返回当前位置的上一级结点,获取你想要的xml_method_call结点。这样所有事情就变得简单了。

      下一个有趣的部分是:

       $conf = new Varien_Object(current($conf)->asArray());
       $add = new Varien_Object($conf->getAdd());
       $code = new Varien_Object($conf->getReturn());
      

      设置我们的$conf, $add和$code作为Varien_Object实例(我们将有自己的getter和setter)。

      最后确认我们的方法是否存在。如果存在就在显示器上打印出结果。

      那么让Magento配置对象呼应我们的模块,接着访问我们的控制器。

      Step 4: Magento, we are here!(Magento,我们在这儿!)

      用下面的代码创建文件app/etc/modules/Alwayly_Xmlmethodcall.xml

      <?xml version="1.0"?>
       
      <config>
      	<modules>
      		<Alwayly_XmlMethodCall>
      			<active>true</active>
      			<codePool>local</codePool>
      		</Alwayly_XmlMethodCall>
      	</modules>
      </config>
      

      Step 5: Visit something like: http://magento1510.loc/index.php/xmlmethodcall(访问类似http://magento1510.loc/index.php/xmlmethodcall的地址)

      你会看到类似这样的结果:

      ID: 101
      VALUE: 100
      CODE: a
       
      ID: 102
      VALUE: 102
      CODE: b
       
      ID: 101
      VALUE: 200
      CODE: a
      Array
      (
          [0] => Array
              (
                  [order_no] => 101
                  [method] => checkmo
                  [amount] => 99
              )
       
          [1] => Array
              (
                  [order_no] => 102
                  [method] => ccsave
                  [amount] => 100
              )
       
          [2] => Array
              (
                  [order_no] => 101
                  [method] => checkmo
                  [amount] => 199
              )
       
      )
      

      我希望你们中的一些人能看到如何使用Varien_Object以及使用XPath表达式会让事情变得多么有趣。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 13 Oct 2015 10:42:18 +0000
      <![CDATA[用*s实现通过Magento后台网格进行搜索]]> https://www.360magento.com/blog/search-through-grids/ 为什么在Magento后台列里搜索某些值时不能使用索引?(例如order#)

      当你的网站有几个管理员的时候,这篇简短的文章将非常有用。我在一个项目中有超过2000个有不同角色的管理员(这个数字还在增长)。你可以想像下当大量管理员在使用后台时是有多慢,特别是他们在搜索或者为数据排序时。

      2000名管理员对Magento来说是个大数字吗?取决于他们如何使用后台部分,但是他们中的大部分要排列东西,搜索些有时他们并不需要的东西。

      在实现新功能前,我们做了一次测试。试图在Magento后台寻找你的销售订单网格中的#: 10。记住有多少搜索结果,花了多长时间。

      为什么通过Magento网格搜索花费如此大?

      因为当你在搜索语句两侧都使用Like语句时MySQL服务不能使用索引。记住MySQL(innodb)有B-Tree索引。

      一个例子,当你想要找出所有使用gmail作为邮箱的客户。你可以搜索Magento后台客户网格的邮箱列,像“@gmail”这样。结果是你找出了所有的gmail邮箱地址。在这个过程中,MySQL浏览所有的客户行和所有的customer_email区域字符在你得到结果前。这种特殊的情况没什么问题,但是当你搜索订单#: 10001时呢?

      同样的事情,因为Magento针对特定的列时,经常在你的字符串前后添加"%"。所以如果你想要搜索#: 10001订单,Magento会转换成“%10001%”并在你的字符串前加Like语句。所以在最后Magento会发送这样的语句到MySQL“SELECT customer_email FROM…. WHERE customer_email LIKE ‘%10001%';这可能不是你所期待的,但它就是这么实现的。

      如果我们想要改变这种行为并给MySQL(Magento)索引提速。我们需要在后台网格搜索时做些改变。最通用和用户友好的方式就是使用"*"字符替换MySQL的特殊字符"%"。

      现在如果你想要使用“like”操作符,你将需要在字符串前、后或两侧添加。所以在我们改变后,你讲能找到所有的gmail通过在你的字符串前后添加"*"。所以,“@gmail”将变成“*@gmail*”。我希望你能看到这背后的思想。

      让我们用下面的内容替换app/code/core/Mage/Adminhtml/Block/Widget/Grid.php中的私有方法_addColumnFilterToCollection($column)。我们只影响sales_order网格。

      /**
       *
       */
      protected function _addColumnFilterToCollection($column)
          {
             if ($this->getCollection()) {
                 $field = ( $column->getFilterIndex() ) ? $column->getFilterIndex() : $column->getIndex();
                 if ($column->getFilterConditionCallback()) {
                     call_user_func($column->getFilterConditionCallback(), $this->getCollection(), $column);
                 } else {
                     $cond = $column->getFilter()->getCondition();
                     /**  START WITH CODE FOR A NEW WAY OF SEARCHING
                      * - if you look in app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Filter/Abstract.php
                      * - you'll see that ->getCondition(); returns an array:
                      * public function getCondition()
                      * {
                      *      return array('like'=>'%'.$this->_escapeValue($this->getValue()).'%');
                      * }
                      * - and _escapeValue returns:
                      * protected function _escapeValue($value)
                      * {
                      *     return str_replace('_', '\_', $value);
                      * }
                      * - so we'll "unescape" it in case where we have [$cond['eq'] and unset($cond['like']);]
                      */
                     if ($field && isset($cond)) {
                         if($this->getAction() instanceof Mage_Adminhtml_Sales_OrderController) {
                             if (isset($cond['like'])) {
       
                                 //cover case where like should go to equal; else means that we have at least one * so like should stay...
                                 if (!(substr($cond['like'], -2) === '*%') && !(substr($cond['like'], 0,2) === '%*')) {
                                     $cond['eq'] = str_replace('%', '', $cond['like']);
                                     $cond['eq'] = str_replace('\_', '_', $cond['eq']); //This line was added with new revision
                                     unset($cond['like']);
                                 } else {
                                     if (substr($cond['like'], 0,2) !== '%*') {
                                         $cond['like'] = substr($cond['like'],1);
                                     } else {
                                         $cond['like'] = '%' . substr($cond['like'],2);
                                     }
                                     if (substr($cond['like'], -2) !== '*%') {
                                         $cond['like'] = substr($cond['like'], 0, -1);
                                     } else {
                                         $cond['like'] = substr($cond['like'], 0, -2) . '%';
                                     }
                                 }
                             }
                         }
                         /*END WITH CODE FOR A NEW WAY OF SEARCHING*/
                         $this->getCollection()->addFieldToFilter($field , $cond);
                     }
                 }
             }
             return $this;
          }
      

      在我们改变Magento核心文件后,再次尝试搜索订单#: 10。现在你能看到多少结果?花了多长时间呢?Magento现在使用order#索引。现在你所能搜索的数字10的类型是:“10”, “*10″, “*10*”和“10*”。注意,只有第一个是同等的,其它的使用了Like语句。

      注意,你可以去掉“if($this->getAction() instanceof Mage_Adminhtml_Sales_OrderController) { … }”这个判断来将改变应用到整个后台。

      你也可以选择重写Mage_Adminhtml_Block_Widget_Grid类而不是修改Magento核心文件。这个小技巧可以有效地提高我们客户的MySQL服务,

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 12 Oct 2015 12:09:21 +0000
      <![CDATA[在单个店铺用所有语言和本地日期打印信息]]> https://www.360magento.com/blog/print-languages-date/ 你是否尝试过在单个页面用所有语言打印一条信息?

      首先,让我来告诉你何时我需要这么做。最近我需要开发一个发送些定制邮件的功能。你已经知道我们可以在网站/店铺设置交易邮件并将这些邮件在administration/db翻译。我所要面对的挑战就是需要翻译一些交易邮件中的随机句子,所以使用预定义的模版是不可能的。在email模版我们是可以用and/or连接变量,但对我来说没什么帮助。

      如果你安装的Magento社区版在1.4.2.0以上,那么我可以开始我们的翻译模块了。

      1. 告诉Magento我们模块的信息;
      2. 创建模块结构;
      3. 编写config.xml;
      4. 编写Translate.php模型;
      5. 编写Locale.php模型;
      6. 编写Data.phph助手;
      7. 编写index.php。

      1.用下面的代码创建app/etc/modules/Alwayly_Translation.xml:

      <?xml version="1.0"?>
      <config>
          <modules>
             <Alwayly_Translate>
                  <active>true</active>
                  <codePool>local</codePool>
              </Alwayly_Translate>
          </modules>
      </config>
      

      2.创建app/code/local/Alwayly/Translate下的文件夹: etc, controllers, Model, Helper

      3.用下面的代码创建app/code/local/Alwayly/Translate/config.xml:

      <?xml version="1.0"?>
      <config>
       
      	<modules>
      		<Alwayly_Translate>
      			<version>0.1.0</version>
      		</Alwayly_Translate>
      	</modules>
       
      	<frontend>
      		<routers>
      			<Alwayly_Translate>
      				<use>standard</use>
      				<args>
      					<module>Alwayly_Translate</module>
      					<frontName>Alwayly</frontName>
      				</args>
      			</Alwayly_Translate>
      		</routers>
      	</frontend>
       
      	<global>
      		<models>
      			<Alwayly_translate>
      				<class>Alwayly_Translate_Model</class>
      			</Alwayly_translate>
       
      			<core>
      				<rewrite>
      					<locale>Alwayly_Translate_Model_Mage_Core_Model_Locale</locale>
      					<translate>Alwayly_Translate_Model_Mage_Core_Model_Translate</translate>
      				</rewrite>
      			</core>
      		</models>
       
      		<helpers>
      			<Alwayly_translate>
      				<class>Alwayly_Translate_Helper</class>
      			</Alwayly_translate>
      		</helpers>
      	</global>
       
      </config>
      

      如你所见,我们需要重写两个Magento模型。我们需要删除一个Translate模型中的if语句,在Locale模型中添加几个“*ByLocaleCode”方法,这样就可以在我们所有的Action里使用商店代码。

      在助手文件中我们将添加方法处理日期(关于本地化)。因为当Magento初始化,一些请求会为特定的本地读取内存中的各种缓存。当你尝试想要做类似的事情:Mage::helper(‘core’)->__(“translate me”)Magento将使用cache/memory。你可以看到:

      /**
       * Translate model
       *
       * @author      Magento Core Team <core@magentocommerce.com>
       */
      class Mage_Core_Model_Translate
      //...
       
      /**
           * Return translated string from text.
           *
           * @param string $text
           * @param string $code
           * @return string
           */
          protected function _getTranslatedString($text, $code)
          {
              $translated = '';
              if (array_key_exists($code, $this->getData())) {
                  $translated = $this->_data[$code];
              }
              elseif (array_key_exists($text, $this->getData())) {
                  $translated = $this->_data[$text];
              }
              else {
                  $translated = $text;
              }
              return $translated;
          }
      

      4.用下面的代码创建app/code/local/app/code/local/Alwayly/Translate/Model/Mage/Core/
      Model/Locale.php/Translate/Model/Mage/Core/Model/Translate.php

      <?php
       
      /**
       * Translate model
       *
       */
      class Alwayly_Translate_Model_Mage_Core_Model_Translate extends Mage_Core_Model_Translate
      {
           /**
           * Retrieve locale
           *
           * @return string
           */
          public function getLocale()
          {
      		$this->_locale = Mage::app()->getLocale()->getLocaleCode();
      		return $this->_locale;
      	}
      }
      

      我们只是移除了getLocale()方法中的if语句。

      5.创建app/code/local/Alwayly/Translate/Model/Mage/Core/Model/Locale.php

      <?php
      /**
       * Locale model
       * 
       */
       
      class Alwayly_Translate_Model_Mage_Core_Model_Locale extends Mage_Core_Model_Locale
      {
          /**
           * Create Zend_Date object with date converted to store timezone and store Locale
           *
           * @param   mixed $store Information about store
           * @param   string|integer|Zend_Date|array|null $date date in UTC
           * @param   boolean $includeTime flag for including time to date
           * @return  Zend_Date
           */
          public function getStoreDate($store=null, $date=null, $includeTime=false)
          {
              $timezone = Mage::app()->getStore($store)->getConfig(self::XML_PATH_DEFAULT_TIMEZONE);
              $locale = Mage::app()->getStore($store)->getConfig(self::XML_PATH_DEFAULT_LOCALE);
              $date = new Zend_Date($date, null, $locale);
              $date->setTimezone($timezone);
              if (!$includeTime) {
                  $date->setHour(0)
                      ->setMinute(0)
                      ->setSecond(0);
              }
              return $date;
          }
       
          /**
      	 * Returns a localized information string, supported are several types of informations.
      	 * For detailed information about the types look into the documentation
      	 *
      	 * @param  string             $value  Name to get detailed information about
      	 * @param  string             $path   (Optional) Type of information to return
      	 * @return string|false The wished information in the given language
      	 */
      	public function getTranslationByLocaleCode($value = null, $path = null, $localeCode = null)
      	{
      		return $this->getLocale()->getTranslation($value, $path, $localeCode/*$this->getLocale()*/);
      	}
      	/**
      	 * Retrieve ISO date format
      	 *
      	 * @param   string $type
      	 * @return  string
      	 */
      	public function getDateFormatByLocaleCode($type=null, $localeCode)
      	{
      		return $this->getTranslationByLocaleCode($type, 'date', $localeCode);
      	}
       
      	/**
      	 * Retrieve ISO time format
      	 *
      	 * @param   string $type
      	 * @return  string
      	 */
      	public function getTimeFormatByLocaleCode($type=null, $localeCode)
      	{
      		return $this->getTranslationByLocaleCode($type, 'time', $localeCode);
      	}
       
      	/**
      	 * Retrieve ISO datetime format
      	 *
      	 * @param   string $type
      	 * @return  string
      	 */
      	public function getDateTimeFormatByLocaleCode($type, $localeCode)
      	{
      		return $this->getDateFormatByLocaleCode($type, $localeCode) . ' ' . $this->getTimeFormatByLocaleCode($type, $localeCode);
      	}
      }
      

      注意,我添加了几个“*ByLocaleCode” 方法,这样能使得Magento核心文件不被修改。

      6、创建助手文件在app/code/local/Alwayly/Translate/Helper/Data.php

      <?php
       
      /**
       * Translate helper
       *
       */
      class Alwayly_Translate_Helper_Data extends Mage_Core_Helper_Abstract
      {
       
      	/**
      	 * Format date using specifed locale
      	 *
      	 * @param   date|Zend_Date|null $date in GMT timezone
      	 * @param   string $format
      	 * @param   bool $showTime
      	 * @return  string
      	 */
      	public function formatDateByLocaleCode($date=null, $format='short', $showTime=false, $localeCode=null)
      	{
      		if ($localeCode === null || !is_string($localeCode)) {
      			$localeCode = Mage::getStoreConfig('general/locale/code');
      		}
      		if (Mage_Core_Model_Locale::FORMAT_TYPE_FULL    	!==$format &&
      				Mage_Core_Model_Locale::FORMAT_TYPE_LONG    !==$format &&
      				Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM  !==$format &&
      				Mage_Core_Model_Locale::FORMAT_TYPE_SHORT   !==$format) {
      			return $date;
      		}
      		if (!($date instanceof Zend_Date) && $date && !strtotime($date)) {
      			return '';
      		}
      		if (is_null($date)) {
      			$date = Mage::app()->getLocale()->date(Mage::getSingleton('core/date')->gmtTimestamp(), null, null);
      		}
      		elseif (!$date instanceof Zend_Date) {
      			$date = Mage::app()->getLocale()->date(strtotime($date), null, null, $showTime);
      		}
       
      		if ($showTime) {
      			$format = Mage::app()->getLocale()->getDateTimeFormatByLocaleCode($format, $localeCode);
      		}
      		else {
      			$format = Mage::app()->getLocale()->getDateFormatByLocaleCode($format, $localeCode);
      		}
      		return $date->toString($format);
      	}
      }
      

      注意,我们最后在if/else判断里调用->getDate(Time/Format)ByLocaleCode方法来替换我们的Locale模型。

      7、创建控制器文件app/code/local/Alwayly/Translate/controllers/IndexController.php

      <?php
       
      /**
       * http://films.local/index.php/ExpiringFilmsNotifier/index/notify
       */
      class Alwayly_Translate_IndexController extends Mage_Core_Controller_Front_Action
      {
          public function translateAction()
          {
          	echo "
      ";
       
          	$defaultStore = Mage::app()->getStore()->getCode();
          	$defaultLocale = Mage::app()->getLocale()->getLocaleCode();
          	$stores = array(1,2,3);
       
          	foreach ($stores as $storeId) {
          		Mage::app()->setCurrentStore($storeId);
          		$currentStore 	= Mage::app()->getStore()->getCode();
          		$currentLocale 	= Mage::getModel('core/locale')->getLocaleCode();
          		Mage::app()->getLocale()->setLocale($currentLocale);
          		// reinitialize translation cache
          		Mage::app()->getTranslator()->init('frontend', true);
       
          		echo Mage::helper('core')->__("Welcome, %s!", Mage::helper('alwayly_translate')
          			->formatDateByLocaleCode('2012-05-05 00:00:00', 'medium', false, $currentLocale))  . PHP_EOL;
          	}
          	//restore app to default values
          	Mage::app()->setCurrentStore($defaultStore);
          	Mage::app()->getLocale()->setLocale($defaultLocale);
          	Mage::app()->getTranslator()->init('frontend', true);
       
          	echo 'Did system restore default initialization?' . PHP_EOL;
          	echo Mage::helper('core')->__("Welcome, %s!", Mage::helper('alwayly_translate')
          			->formatDateByLocaleCode('2012-05-05 00:00:00', 'medium', false, $currentLocale))  . PHP_EOL;
          	exit;
          }
      }
      

      注意,我们先创建了两个变量$defaultStore和$defaultLocale,这样我妈就可以在customer页面回复Magento自定义。如果你有三个店铺确认为它们设置了本地化。

      我在in app/etc/locale/de_DE/和app/etc/locale/fr_FR/ 创建了Mage_Page.csv ,代码如下:

      For German:
      “Welcome, %s!”,”de_DE Welcome, %s!”
      For France :
      “Welcome, %s!”,”fr_FR Welcome, %s!”
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 12 Oct 2015 11:49:34 +0000
      <![CDATA[编程的方式创建,应用和删除Magento中的购物车价格规则]]> https://www.360magento.com/blog/price-rule-magento/ 默认的Magento中有个很棒的功能叫做“促销”。有两种类型的促销:目录价格跪着和购物车价格规则。这篇文章中我将演示如何以编程的方式来创建,应用和删除购物车价格规则。

      有很多理由让你使用它。例如:你想模拟某种奖励功能,对达到要求的客户进行打折。除非正在使用Magento EE就不用了(带有奖励积分的功能),那么你将编写代码或者购买第三方插件。我个人不太喜欢用第三方插件,除非它是必须的或者能达到功能需求的90-95%。否则你将花费时间在修改插件上。让我们看看我们如何自己实现这个功能。一种方式是用代码粉方式创建和应用购物车价格规则,然后在执行的时候删除购物车价格规则。

      首先,我们创建购物车价格规则。我们将以手动创建一个规则,然后学习后台进程来以编程的方式来复制它。我们将进入Magento后台,在“Promotions > Shopping Cart Price Rules”下,点击“Add New Rule”右上角按钮。在这个例子中,我们将限制一个客户每次只能使用一个优惠券。我们填上必须字段并用POST变量提交数据,最后的url会像这样:http://shop.net/index.php/admin/promo_quote/save/

      form_key => YYhUwcLXX6sezYPY
      product_ids => 
      name => CUSTOMER_1 - 30% Summer discount
      description => 
      is_active => 1
      website_ids[] => 1
      customer_group_ids[] => 3
      coupon_type => 2
      coupon_code => leIYc4g1dbCCOlT1
      uses_per_coupon => 1
      uses_per_customer => 1
      from_date => 
      to_date => 
      sort_order => 
      is_rss => 1
      rule[conditions][1][type] => salesrule/rule_condition_combine
      rule[conditions][1][aggregator] => all
      rule[conditions][1][value] => 1
      rule[conditions][1][new_child] => 
      simple_action => by_percent
      discount_amount => 30
      discount_qty => 0
      discount_step => 
      apply_to_shipping => 0
      simple_free_shipping => 0
      stop_rules_processing => 0
      rule[actions][1][type] => salesrule/rule_condition_product_combine
      rule[actions][1][aggregator] => all
      rule[actions][1][value] => 1
      rule[actions][1][new_child] => 
      store_labels[0] => 
      store_labels[1] => 
      

      现在,如果我们研究http://shop.net/index.php/admin/promo_quote/save/ 后面的Mage_Adminhtml_Promo_QuoteController -> saveAction(),我们可以看到规则的创建:

      $data = array(
          'product_ids' => null,
          'name' => sprintf('AUTO_GENERATION CUSTOMER_%s - 30%% Summer discount', Mage::getSingleton('customer/session')->getCustomerId()),
          'description' => null,
          'is_active' => 1,
          'website_ids' => array(1),
          'customer_group_ids' => array(1),
          'coupon_type' => 2,
          'coupon_code' => Mage::helper('core')->getRandomString(16),
          'uses_per_coupon' => 1,
          'uses_per_customer' => 1,
          'from_date' => null,
          'to_date' => null,
          'sort_order' => null,
          'is_rss' => 1,
          'rule' => array(
              'conditions' => array(
                  array(
                      'type' => 'salesrule/rule_condition_combine',
                      'aggregator' => 'all',
                      'value' => 1,
                      'new_child' => null
                  )
              )
          ),
          'simple_action' => 'by_percent',
          'discount_amount' => 30,
          'discount_qty' => 0,
          'discount_step' => null,
          'apply_to_shipping' => 0,
          'simple_free_shipping' => 0,
          'stop_rules_processing' => 0,
          'rule' => array(
              'actions' => array(
                  array(
                      'type' => 'salesrule/rule_condition_product_combine',
                      'aggregator' => 'all',
                      'value' => 1,
                      'new_child' => null
                  )
              )
          ),
          'store_labels' => array('30% Summer discount')
      );
       
      $model = Mage::getModel('salesrule/rule');
      $data = $this->_filterDates($data, array('from_date', 'to_date'));
       
      $validateResult = $model->validateData(new Varien_Object($data));
       
      if ($validateResult == true) {
       
          if (isset($data['simple_action']) && $data['simple_action'] == 'by_percent'
                  && isset($data['discount_amount'])) {
              $data['discount_amount'] = min(100, $data['discount_amount']);
          }
       
          if (isset($data['rule']['conditions'])) {
              $data['conditions'] = $data['rule']['conditions'];
          }
       
          if (isset($data['rule']['actions'])) {
              $data['actions'] = $data['rule']['actions'];
          }
       
          unset($data['rule']);
       
          $model->loadPost($data);
       
          $model->save();
      }
      

      上面涵盖了“create”部分,现在让我们转到应用部分。想法是:在执行chechout之前以编程的方式来应用优惠券。如果我们在像http://shop.net/checkout/cart/这样的url里应用优惠券,表单可能提交数据到http://shop.net/checkout/cart/couponPost/的controller动作。

      提交数据非常简单:

      remove => 0
      coupon_code => da4K53cGuhNoTc10
      

      现在,让我们看看http://shop.net/checkout/cart/couponPost/后面的controller动作。我们要看得更远点,我们将先寻找之前我们创建的特殊规则名。当筛选出特殊的数据check等等时。你留下类似“apply Shopping Cart Price Rule”代码的东西。

      /* START This part is my extra, just to load our coupon for this specific customer */
      $model = Mage::getModel('salesrule/rule')
              ->getCollection()
              ->addFieldToFilter('name', array('eq'=>sprintf('AUTO_GENERATION CUSTOMER_%s - 30%% Summer discount', Mage::getSingleton
      
      ('customer/session')->getCustomerId())))
              ->getFirstItem();
       
      $couponCode = $model->getCouponCode();
      /* END This part is my extra, just to load our coupon for this specific customer */
       
      Mage::getSingleton('checkout/cart')
          ->getQuote()
          ->getShippingAddress()
          ->setCollectShippingRates(true);
       
      Mage::getSingleton('checkout/cart')
          ->getQuote()
          ->setCouponCode(strlen($couponCode) ? $couponCode : '')
          ->collectTotals()
          ->save();
      

      现在我们需要做的就是这个代码转移到合适的位置,像事件观察。最后一旦客户结账完成,我们就用一个简单的代码删除这个规则。

      $model = Mage::getModel('salesrule/rule')
              ->getCollection()
              ->addFieldToFilter('name', array('eq'=>sprintf('AUTO_GENERATION CUSTOMER_%s - 30%% Summer discount', Mage::getSingleton('customer/session')->getCustomerId())))
              ->getFirstItem();
       
      $model->delete();
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 11 Oct 2015 15:44:35 +0000
      <![CDATA[Magento前台隐藏送货方式,但在后台保留]]> https://www.360magento.com/blog/hide-shipping-method/ 对于你们中的某些人,这可能是个惊喜,但是Magento不支持在前台禁止Magento方法但在后台保留。你也许可以做些调整配置来达到效果,但那不是100%正确的。虽然Magento支持“global/website/store”设置,在全球和网站级别,运输方法被打开或者关闭。在商店级别,你可以简单的编辑运输方式的title和其它东西,但你不能打开/关闭运输方式。

      现在,想像下你Magento系统里只有一个网站,如果你在后台“Sales > Orders”点击“Create New Order”按钮。下面你将看到“please select a customer”来选择你想要创建订单的客户。但当你的Magento系统中有两个或更多网站时,你在后台“Sales > Orders”点击“Create New Order”按钮,下一个出来的就是“please select a website” ,之后才会看到“please select a customer”。这意味着Magento使用默认的网站或者你选择的网站来创建用户订单。无论哪种方式,它都从网站读取配置和运输数据。这意味着这种设置没办法在后台只显示某某运输方式……

      我们如何绕过这点?简单,只需要重写Mage_Shipping_Model_Config和Mage_Sales_Model_Quote_Address。注意,这不一定是最好或者最优的方法,但却是一个可行的方法。

      app/code/local/Mycompany/Myextension/etc/config.xml

      <models>
          <shipping>
              <rewrite>
                  <config>Mycompany_Myextension_Model_Shipping_Config</config>
              </rewrite>                
          </shipping>
          <sales>
              <rewrite>
                  <quote_address>Mycompany_Myextension_Model_Sales_Quote_Address</quote_address>
              </rewrite>
          </sales>
      </models>
      

      app/code/local/Mycompany/Myextension/Model/Adminhtml/System/Config/Source/Shipping/Methods.php

      <?php
       
      class Mycompany_Myextension_Model_Adminhtml_System_Config_Source_Shipping_Methods 
      {
          protected $_options;
       
          public function toOptionArray()
          {
              $carriers = Mage::getSingleton('shipping/config')->getAllCarriers();
       
              $carriersActive = Mage::getSingleton('shipping/config')->getActiveCarriers();
              $carriersActive = array_keys($carriersActive);
       
              if (!$this->_options) {
                  foreach ($carriers as $carrier) {
                      $carrierCode = $carrier->getId();
                      $carrierTitle = Mage::getStoreConfig('carriers/'.$carrierCode.'/title', Mage::app()->getStore()->getId());
                      $carrierTitle = trim($carrierTitle);
       
                      if (empty($carrierTitle)) {
                          continue;
                      }
       
                      if (in_array($carrierCode, $carriersActive)) {
                          $carrierTitle = sprintf('%s (currently active)', $carrierTitle);
                      } else {
                          $carrierTitle = sprintf('%s (currently inactive)', $carrierTitle);
                      }
       
                      $this->_options[] = array('value'=>$carrierCode, 'label'=>$carrierTitle);
                  }
              }
       
              $options = $this->_options;
       
              array_unshift($options, array('value'=>'', 'label'=> ''));
       
              return $options;
          }
      }
      

      这个文件被systemxml的“source_model”定义调用

      <fields>
          <frontend_hidden_methods>
              <label>Hide Shipping Methods on Frontend</label>
              <comment></comment>
              <frontend_type>multiselect</frontend_type>
              <source_model>mycompany_myextension/adminhtml_system_config_source_shipping_methods</source_model>
              <sort_order>2</sort_order>
              <show_in_default>1</show_in_default>
              <show_in_website>1</show_in_website>
              <show_in_store>1</show_in_store>
          </frontend_hidden_methods>
      </fields>
      

      注意!上面的system.xml只是部分的,只用于实际字段的配置定义。

      app/code/local/Mycompany/Myextension/Helper/Data.php

      <?php
       
      class Mycompany_Myextension_Helper_Data extends Mage_Core_Helper_Abstract
      {
          const CONFIG_PATH_HIDE_FRONTEND_SHIPPING_METHODS = 'some-path-to-system-xml-field';
       
          public function getHiddenFrontendShippingMethods()
          {
              $methods = Mage::getStoreConfig(self::CONFIG_PATH_HIDE_FRONTEND_SHIPPING_METHODS);
              $methods = explode(',', $methods);
       
              return $methods;
          }
      }
      

      app/code/local/Mycompany/Myextension/Model/Shipping/Config.php

      <?php
       
      class Mycompany_Myextension_Model_Shipping_Config extends Mage_Shipping_Model_Config
      {
          public function getActiveCarriers($store = null)
          {
              $carriers = parent::getActiveCarriers($store);
       
              if (Mage::getDesign()->getArea() === Mage_Core_Model_App_Area::AREA_FRONTEND) {
       
                  $carriersCodes = array_keys($carriers);
                  $hiddenShippingMethods = Mage::helper('mycompany_myextension')->getHiddenFrontendShippingMethods();
       
                  foreach ($carriersCodes as $carriersCode) {
                      if (in_array($carriersCode, $hiddenShippingMethods)) {
                          unset($carriers[$carriersCode]);
                      }
                  }            
              }
       
              return $carriers;
          }
      }
      

      app/code/local/Mycompany/Myextension/Model/Sales/Quote/Address.php

      <?php
       
      class Mycompany_Myextension_Model_Sales_Quote_Address extends Mage_Sales_Model_Quote_Address
      {
          public function getShippingRatesCollection()
          {
              parent::getShippingRatesCollection();
       
              $hiddenFrontendShippingMethods = Mage::helper('mycompany_myextension')->getHiddenFrontendShippingMethods();
       
              $removeRates = array();
       
              foreach ($this->_rates as $key => $rate) {
                  if (in_array($rate->getCarrier(), $hiddenFrontendShippingMethods)) {
                      $removeRates[] = $key;
                  }   
              }
       
              foreach ($removeRates as $key) {
                  $this->_rates->removeItemByKey($key);
              }
       
              return $this->_rates;
          }
      }
      

      基本上就是这样了。现在你的后台里有了多选框来选择特定的方法在前台隐藏后台保留。记住,运输方式必须是开启的,不要和启用/禁止“hide on frontend”相混淆。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 11 Oct 2015 15:39:14 +0000
      <![CDATA[在Magento中自定义路由器]]> https://www.360magento.com/blog/custom-router-magento/ 当我们想要分开同一路由的一些业务逻辑而又不想重定向到控制器里的其它路由时,创建自定义路由器是非常有的。

      为什么我们不为不同的逻辑创建分开的独立的路由呢?

      我来稍微解释下:我结合一个我们项目中的OneStepCheckout插件(已经重写了Core Checkout路由)来谈下。我需要重写路由,根据URL中的字段将它们分到两个不同的控制器中。我发现最好的方法就是创建一个新的路由器重定向到由字段决定的不同控制器。

      在“…/app/code/local/Mynamespace/Myextension/etc/config.xml”创建我们自己的路由器

      <default>
          <web>
            <routers>
               <myextension_myrouter>
                   <area>frontend</area>
                   <class>Mynamespace_Myextension_Controller_Router</class>
               </myextension_myrouter>
           </routers>
          </web>
         </default>
       </stores>
      

      在 “…/app/code/local/Mynamespace/Myextension”新建Controller文件夹,在文件夹里新建Mynamespace_Myextension_Controller_Router.php文件:

      <?php
      //Mynamespace_Myextension_Controller_Router.php
       
      /**
       * Router for deciding to go on party checkout or regular onestepcheckout
       */
      class Mynemaspace_Myextension_Controller_Router extends 
      
      Mage_Core_Controller_Varien_Router_Standard {
       
       
      }
      ?>
      

      拷贝Mage_Core_Controller_Varien_Router_Standard.php中对应的方法到我们的类,进行修改:

      /**
           * Match the request
           *
           * @param Zend_Controller_Request_Http $request
           * @return boolean
           */
          public function match(Zend_Controller_Request_Http $request)
          {
              //checking before even try to find out that current module
              //should use this router
              if (!$this->_beforeModuleMatch()) {
                  return false;
              }
       
              $this->fetchDefault();
       
              $front = $this->getFront();
              $path = trim($request->getPathInfo(), '/');
       
              if ($path) {
                  $p = explode('/', $path);
              } else {
                  $p = explode('/', $this->_getDefaultPath());
              }
       
              // get module name
              if ($request->getModuleName()) {
                  $module = $request->getModuleName();
              } else {
                  if (!empty($p[0])) {
                      $module = $p[0];
                  } else {
                      $module = $this->getFront()->getDefault('module');
                      $request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, '');
                  }
              }
              if (!$module) {
                  if (Mage::app()->getStore()->isAdmin()) {
                      $module = 'admin';
                  } else {
                      return false;
                  }
              }
       
              /**
               * Searching router args by module name from route using it as key
               */
              $modules = $this->getModuleByFrontName($module);
       
              if ($modules === false) {
                  return false;
              }
       
              //checkings after we foundout that this router should be used for current module
              if (!$this->_afterModuleMatch()) {
                  return false;
              }
       
              /**
               * Going through modules to find appropriate controller
               */
              $found = false;
              foreach ($modules as $realModule) {
                  $request->setRouteName($this->getRouteByFrontName($module));
       
                  // get controller name
                  if ($request->getControllerName()) {
                      $controller = $request->getControllerName();
                  } else {
                      if (!empty($p[1])) {
                          $controller = $p[1];
                      } else {
                          $controller = $front->getDefault('controller');
                          $request->setAlias(
                              Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
                              ltrim($request->getOriginalPathInfo(), '/')
                          );
                      }
                  }
       
                  // get action name
                  if (empty($action)) {
                      if ($request->getActionName()) {
                          $action = $request->getActionName();
                      } else {
                          $action = !empty($p[2]) ? $p[2] : $front->getDefault('action');
                      }
                  }
       
                  //checking if this place should be secure
                  $this->_checkShouldBeSecure($request, '/'.$module.'/'.$controller.'/'.$action);
       
                  $controllerClassName = $this->_validateControllerClassName($realModule, $controller);
                  if (!$controllerClassName) {
                      continue;
                  }
       
                  // instantiate controller class
                  $controllerInstance = Mage::getControllerInstance($controllerClassName, $request, 
      
      $front->getResponse());
       
                  if (!$controllerInstance->hasAction($action)) {
                      continue;
                  }
       
                  $found = true;
                  break;
              }
       
              /**
               * if we did not found any siutibul
               */
              if (!$found) {
                  if ($this->_noRouteShouldBeApplied()) {
                      $controller = 'index';
                      $action = 'noroute';
       
                      $controllerClassName = $this->_validateControllerClassName($realModule, 
      
      $controller);
                      if (!$controllerClassName) {
                          return false;
                      }
       
                      // instantiate controller class
                      $controllerInstance = Mage::getControllerInstance($controllerClassName, $request,
                          $front->getResponse());
       
                      if (!$controllerInstance->hasAction($action)) {
                          return false;
                      }
                  } else {
                      return false;
                  }
              }
       
              // set values only after all the checks are done
              $request->setModuleName($module);
              $request->setControllerName($controller);
              $request->setActionName($action);
              $request->setControllerModule($realModule);
       
              // set parameters from pathinfo
              for ($i = 3, $l = sizeof($p); $i < $l; $i += 2) {
                  $request->setParam($p[$i], isset($p[$i+1]) ? urldecode($p[$i+1]) : '');
              }
       
              // dispatch action
              $request->setDispatched(true);
              $controllerInstance->dispatch($action);
       
              return true;
          }
      

      例如,现在我想重定向路由到“Party”控制器。我们可以给控制器名添加前缀。一般控制器是:Mynamespace/Myextension/controllers/Somecontrollername.php,“Party”控制器就是:Mynamespace/Myextension/controllers/Party/Somecontrollername.php。要实现这个,那么我们需要在上面代码的57行到62行之间添加些代码:

      $party_prefix = '';
       
              if ($this->isPartyOrder($request)) {
                  foreach ($modules as $key => $realModule) {
                      $modules[$key].='_Party';
                  }
       
                  $party_prefix = '_party';
              }
      

      当然,我们的isParty方法是这样的:

      ..
          /**
           * Determine if order is "Party order"
           * @param Mage_Core_Controller_Request_Http $request
           * @return boolean
           */
          private function isPartyOrder($request) {
       
              if (isset($_SESSION['is_party_checkout']) && $_SESSION['is_party_checkout']) {
                  return true;
              }
       
              $pathInfo = $request->getPathInfo();
       
              if (stristr($pathInfo, 'onestepcheckout/index/index')) {
                  $params = Mage::app()->getRequest()->getParams();
                  if (isset($params['id'])) {
                      return true;
                  }
              }
       
              return false;
          }
      ..
      

      这里,我们检查Party是否在session或者URL的GET参数里。

      下一步,让我们修改一个将被layout.xml文件使用的路由名,替换这段代码

      /**
               * Going through modules to find appropriate controller
               */
              $found = false;
              foreach ($modules as $realModule) {
                  $request->setRouteName($this->getRouteByFrontName($module));
      

      //...
              /**
               * Going through modules to find appropriate controller
               */
              $found = false;
              foreach ($modules as $realModule) {
                  $request->setRouteName('ourextension_' . $this->getRouteByFrontName($module) . 
      
      $party_prefix);
              ...
      //...
      

      现在我们可以在布局xml文件里定义布局句柄来将“Party” 和其它路由区分开。

      <?xml version="1.0"?>
      <layout version="0.1.0">
          <<ourmodule_controllername_actionname>
            <block ....... some layout updates ... etc
          </ourmodule_controllername_actionname>
       
         <ourmodule_party_controllername_actionname>
            <block ....... some different layout updates ... etc
         </ourmodule_party_controllername_actionname>
      </layout>
      

      这样我们就可以单独实现两种完全不同的布局。这只是个简单的例子来创建和修改路由器。你可以定制自己的路由器来实现你的需求。

      下面让我们看看onestepcheckout的config.xml文件,看它的路由器是如何设置模块的:

      <frontend>
              <routers>
                  <onestepcheckout>
                      <use>myextension_myrouter</use>
                      <args>
                         <modules>
                              <Mynamespace_Mymodule before="Idev_OneStepCheckout">Mynamespace_Mymodule_Onestepcheckout</Mynamespace_Mymodule>
                          </modules>
                      </args>
                  </onestepcheckout>
              </routers>
      

      Onestepcheckout模块重写一些Magento核心路由,这样当客户访问checkout/onepage地址时,他们会得到 onestepcheckout地址。

      当我们创建像上面的自定义路由器时,客户仍然会访问onestepcheckout路由,但会根据isParty的判断结果来执行不同的控制器。

      由于同样的URL分为Party和regular支付,我们在路由里为每个支付状态(Party and regular) 设置自定义路由名而更新xml句柄。

      虽然第一次读起来可能会有些乱,但我希望在某些人的项目,插件和定制中起到作用。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 10 Oct 2015 13:11:02 +0000
      <![CDATA[ 在Magento的销售网格中添加“用户组”列]]> https://www.360magento.com/blog/customer-group-sales/ 令人惊讶的是Magento后台的“Sales > Orders”和“Sales > Orders > Create New Order” 网格里没有“用户组”这一列。为什么我们需要这一列呢?也许你需要在网格中列出/筛选“经销商”组支付的订单。也许你能够筛选 “Sales > Orders > Create New Order” 网格通过在创建订单前的用户组来查看“经销商”客户数量。

      默认情况下“Sales > Orders” 网格使用“sales_flat_order_grid”进行渲染。这个表基本上是“sales_flat_order”表的冗余子组。令人惊讶的是“sales_flat_order” 表里有“customer_group_id”列,而“sales_flat_order_grid”表中没有。所以我们第一步就是要添加“customer_group_id”列到“sales_flat_order_grid”表中。

      我们通过一个类似这样的简单升级脚本来实现:

      $installer->getConnection()
              ->addColumn($installer->getTable('sales/order_grid'), 'customer_group_id', array(
                  'TYPE' => Varien_Db_Ddl_Table::TYPE_SMALLINT,
                  'NULLABLE'  => false,
                  'DEFAULT'   => '0',
                  'COMMENT' => 'Customer Group'
              ));
      

      如果这个安装/升级脚本执行成功,我们就会在“sales_flat_order_grid”表中看到“customer_group_id”列。注意,Magento会在新订单保存时自动填充“sales_flat_order_grid.customer_group_id”中的数据。

      然后我们将重写Mage_Adminhtml_Block_Sales_Order_Grid和Mage_Adminhtml_Block_Sales_Order_Create_Customer_Grid。但只做些小的修改来让我们的“Customer Group”显示。

      我们通过config.xml来添加合适的入口:

      <global>
          <blocks>
              <adminhtml>
                  <rewrite>      <sales_order_create_customer_grid>Mycompany_Myextension_Block_Adminhtml_Sales_Order_Create_Customer_Grid</sales_order_create_customer_grid>
                      <sales_order_grid>Mycompany_Myextension_Block_Adminhtml_Sales_Order_Grid</sales_order_grid>
                  </rewrite>
              </adminhtml>
          </blocks>
      </global>
      

      最后,添加重写模块

      <?php
       
      class Mycompany_Myextension_Block_Adminhtml_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid 
      {
          protected function _prepareColumns()
          {
              $groups = Mage::getResourceModel('customer/group_collection')
                  ->addFieldToFilter('customer_group_id', array('gt'=> 0))
                  ->load()
                  ->toOptionHash();
       
              $this->addColumn('customer_group_id', array(
                  'header'    =>  Mage::helper('customer')->__('Customer Group'),
                  'width'     =>  '100',
                  'index'     =>  'customer_group_id',
                  'type'      =>  'options',
                  'options'   =>  $groups,
              ));
       
              $this->addColumnsOrder('customer_group_id', 'shipping_name');
       
              return parent::_prepareColumns();
          }
      }
      
      <?php
       
      class Mycompany_Myextension_Block_Adminhtml_Sales_Order_Create_Customer_Grid extends 
      
      Mage_Adminhtml_Block_Sales_Order_Create_Customer_Grid
      {
          protected function _prepareColumns()
          {
              $groups = Mage::getResourceModel('customer/group_collection')
                  ->addFieldToFilter('customer_group_id', array('gt'=> 0))
                  ->load()
                  ->toOptionHash();
       
              $this->addColumn('group', array(
                  'header'    =>  Mage::helper('customer')->__('Group'),
                  'width'     =>  '100',
                  'index'     =>  'group_id',
                  'type'      =>  'options',
                  'options'   =>  $groups,
              ));
       
              $this->addColumnsOrder('group', 'email');
       
              return parent::_prepareColumns();
          }
      }
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 10 Oct 2015 12:52:38 +0000
      <![CDATA[Magento中创建简单的社交链接]]> https://www.360magento.com/blog/simple-social-sharing/ 有很多方法来添加社交共享按钮到你的Magento商店。你可以选择几种不同的免费或者付费的插件,创建自己的,使用AddThis服务或者从官方粘贴脚本(像 Facebook Like)。然而,在设置样式是会收到一些限制。如果你需要一个简单的解决方法,那么这篇文章适用于你。

      我将指出一些你应该知道的官方按钮潜在问题。首先,你生成的每个按钮有一些JavaScript代码。这些代码在远程服务器上,每次用户打开一个页面时被读取。虽然这些代码的读取是异步的,但是当你有很多这些代码时会影响页面读取速度。另一方面,如果这些按钮有些复杂(或者写得不好的)JavaScript可能会弄乱你的商店。有一次我用AddThis插件在Magento产品页面添加社交按钮时,可配置产品因为Twitter按钮而失效,总价不更新,“添加产品到购物车”无效。我记不清具体的报错JavaScript代码但是我认为和全局变量名或者类似的东西相关。重点是,这些按钮会产生一些问题,让你话费不必要的时间去调试。我已经记不清多少次因为Facebook Like按钮失效而让我绝望了。

      把事情简单化

      我总是让喜欢让事情简单地工作。每一个社交网站都有一个简单的接受一些基础参数的“共享地址”,允许你分享任何URL。因为这是一个简单的URL,你能以你喜欢的风格做一个链接或者任何类型的按钮。另外一个好处就是,使用简单“共享地址”是没有外部脚本的。

      下面是一些流行的社交网站共享URL:

      • Google Plus: https://plus.google.com/share?url=[URL TO SHARE]
      • Facebook: https://www.facebook.com/sharer/sharer.php?u=[URL TO SHARE]&t=[TITLE]
      • Twitter: http://twitter.com/home/?status=[TITLE] ([URL TO SHARE])
      • Pinterest: https://pinterest.com/pin/create/button/?url=[LINKBACK URL]&media=[IMAGE TO SHARE]& description=[DESCRIPTION]

      实现

      如果你关注可用性,那么利用打开新窗口的方式来远离简单链接元素并不是一个完美的解决方案。最简单的方式就是以弹窗的方式打开链接。如果你的网站里有些这样的JavaScript模式,你可以使用它们。但为了简单起见,我将使用默认的Magento弹出窗口。

      社交按钮最合理的位置当然是产品页面了,所以我们以此为例。我将添加Google Plus, Facebook, Twitter 和Pinterest按钮,但我不确定你能轻易地添加其它社交网站。为了与文章标题一致,我将添加简单的链接而不是按钮,但是你可以用一些基础的CSS来创建按钮。

      跟着下面这些简单的步骤你就能轻易地拥有社交共享链接。

      打开app/design/frontend/YOUR_PACKAGE/YOUR_THEME/template/catalog/product/view.phtml找到你要添加链接/按钮的位置,添加下面的代码:

      <?php $productName = $_helper->productAttribute($_product, $_product->getName(), 'name'); ?>
      <?php $productUrl = $_helper->productAttribute($_product, $_product->getProductUrl(), 'product_url'); ?>
      <?php $productImage = $_product->getImageUrl() ?>
      

      我们将使用这些变量来设置URL,标题,描述或者其它需要的字段。在我们刚才添加的代码后面添加:

      // Google Plus
      <a href="javascript:popWin('https://plus.google.com/share?url=<?php echo urlencode($productUrl); ?>', 'google', 'width=640,height=480,left=0,top=0,location=no,status=yes,scrollbars=yes,resizable=yes');" title="<?php echo $this->__('Share on Google Plus') ?>">Google Plus</a>
      // Facebook
      <a href="javascript:popWin('https://www.facebook.com/sharer/sharer.php?u=<?php echo urlencode($productUrl); ?>&t=<?php echo urlencode($productName); ?>', 'facebook', 'width=640,height=480,left=0,top=0,location=no,status=yes,scrollbars=yes,resizable=yes');" title="<?php echo $this->__('Share on Facebook') ?>">Facebook</a>
      // Twitter
      <a href="javascript:popWin('http://twitter.com/home/?status=<?php echo urlencode($productName . ' (' . $productUrl . ')'); ?>', 'twitter', 'width=640,height=480,left=0,top=0,location=no,status=yes,scrollbars=yes,resizable=yes');" title="<?php echo $this->__('Tweet') ?>">Twitter</a>
      // Pinterest
      <a href="javascript:popWin('https://pinterest.com/pin/create/button/?url=<?php echo urlencode($productUrl); ?>&media=<?php echo urlencode($productImage); ?>&description=<?php echo urlencode($productName); ?>', 'pinterest', 'width=640,height=480,left=0,top=0,location=no,status=yes,scrollbars=yes,resizable=yes');" title="<?php echo $this->__('Pin it') ?>">Pinterest</a>
      

      尽管所有社交网站都善于提取你共享链接的内容(产品名称,图片,描述……)但尽可能地帮助它们也是很好的做法。最常用的做法就是为你的页面添加meta标签。你有许多不同的方法可用,但是为了简单起见,我将使用OpenGraph,因为Facebook在用它。如果你的页面有些复杂的改变,它将不会正确地提取产品信息。

      另一方面,使用分享链接在Google Plus提取产品信息时我没遇到过任何问题。Twitter简单些,因为你只分享了定义的文本。Pinterest要求你指定所有的信息,所以这些站不需要meta标签。

      添加OpenGraph meta标签到你的Magento商店非常简单。只要添加下面的代码到app/design/frontend/YOUR_PACKAGE/YOUR_THEME/template/page/html/head.phtml的最后一个meta标签后面(如果你用Magento默认的head文件就是名为“robots”meta标签)。

      <?php $product = Mage::registry('current_product');
      if ($product): ?>
      <meta property="og:title" content="<?php echo $product->getName(); ?>" />
      <meta property="og:type" content="product" />
      <meta property="og:url" content="<?php echo $this->helper('catalog/product')->getProductUrl($product); ?>" />
      <meta property="og:image" content="<?php echo $this->helper('catalog/image')->init($product, 'image')->resize(300, 300); ?>" />
      <meta property="og:description" content="<?php echo strip_tags($product->getShortDescription()); ?>" />
      <meta property="og:site_name" content="<?php echo Mage::app()->getStore()->getName() ?>" />
      <?php endif; ?>
      

      我们共享一个产品,所以我们需要在meta标签添加到唯一的产品页面,但head.phtml的每一页上加载。这意味着,我们需要检查,如果当前页面是产品页面,然后才加入我们的meta标签。同时,我们需要得到的产品对象,所以我们可以提取我们需要投入meta标签中的数据。在上面的代码中的前两行会做到这一点。我们创建一个变量$product来获取当前的产品。如果我们在产品页面,这个变量将包含当前产品的对象。如果不是,$product会被设置为false。我用一些标准的meta标签去描述产品,但你可以按需使用更多标签。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 09 Oct 2015 13:13:53 +0000
      <![CDATA[选择一个合适的事件去监听]]> https://www.360magento.com/blog/right-event-observe/ 当你开发你的Magento模块或者通过事件监听做修改时,选对合适的事件是非常重要的。

      一个方法是在你的PHP IDE里搜索Magento核心文件“Mage::dispatchEvent(“,结果大概会出现400处。大部分这些方法调用静态字符串作为事件名称,如:

      Mage::dispatchEvent('catalog_product_is_salable_before', array('product' => $this));

      也有些事件的名字是由一些变量串联到静态字符串组成的,如:

      Mage::dispatchEvent($this->_eventPrefix.'_validate_before', array($this->_eventObject=>$this));

      在这种情况下,我们不能确定最终的事件名称。由于Magento不允许我们同时观察超过一个事件,我们要想办法得到一个确定需求的所有事件。

      如果我们查看app/Mage.php中声明的Mage::dispatchEvent,你可以看到以下代码:

      public static function dispatchEvent($name, array $data = array())
          {
              Varien_Profiler::start('DISPATCH EVENT:'.$name);
              $result = self::app()->dispatchEvent($name, $data);
              #$result = self::registry('events')->dispatch($name, $data);
              Varien_Profiler::stop('DISPATCH EVENT:'.$name);
              return $result;
          }

      我们不能重写Mage类去添加事件名称抓取功能。Mage::dispatchEvent方法从Mage_Core_Model_App调用dispatchEvent方法。我们也不能重写Mage_Core_Model_App,因为应用程序对象被直接实例化,而不是从Mage::getModel工厂方法。所以,获取指定需求的所有事件名称的唯一方法就是在Mage::dispatchEvent中添加一个简单的硬编码行。我们可以加类似这样的东西:

      Mage::log($name, null, 'events.log', true);

      它记录需求中被调用的每一个事件的名称。app/Mage.php里的dispatchEvent方法被修改后看起来像是这样的:

      public static function dispatchEvent($name, array $data = array())
          {
              // log event name
              Mage::log($name, null, 'events.log', true);
       
              Varien_Profiler::start('DISPATCH EVENT:'.$name);
              $result = self::app()->dispatchEvent($name, $data);
              #$result = self::registry('events')->dispatch($name, $data);
              Varien_Profiler::stop('DISPATCH EVENT:'.$name);
              return $result;
          }

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 09 Oct 2015 13:02:28 +0000
      <![CDATA[Magento自动识别性别的插件]]> https://www.360magento.com/blog/magento-automatic-gender/ 今天我们要为客户创建一个Magento自动识别性别的插件。插件基于Rapleaf的个性化API。Rapleaf公司提供人口统计和消费者个人数据(年龄,性别,婚姻状况,收入等),不能用作商业电子邮件。他们的合作伙伴,一些大(小)型数据公司将数据汇总并绑定到邮箱地址。你可以创建一个免费的Rapleaf账户来获取API。 让我们开始吧。

      Alwayly_Autogender.xml

      首先,我们要在/app/etc/modules文件夹里创建Alwayly_Autogender.xml

      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Autogender>
                 <active>true</active>
                  <codePool>local</codePool>
              </Alwayly_Autogender>
         </modules>
      </config>

      config.xml

      第二步是在 /app/code/local/Alwayly/Autogender/etc文件夹里创建config.xml

      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Autogender>
                  <version>0.1.0</version>
              </Alwayly_Autogender>
          </modules>
          <global>
              <models>
                  <alwayly_autogender>
                      <class>Alwayly_Autogender_Model</class>
                  </alwayly_autogender>
              </models>
              <events>
                  <customer_register_success>
                      <observers>
                          <alwayly_autogender_add_email>
                              <class>alwayly_autogender/observer</class>
                              <method>getGender</method>
                          </alwayly_autogender_add_email>
                      </observers>
                  </customer_register_success>
              </events>
          </global>
      </config>

      Observer.php

      最后一步是/app/code/local/Alwayly/Autogender/Model文件夹里创建Observer.php

      <?php
       
      class Alwayly_Autogender_Model_Observer
      {
          public function getGender($observer = null)
          {
              if($observer)
              {
                  try
                  {
                      $customer = $observer->getCustomer();
       
                      $api_key = '... your api key ...';
       
                      $client = new Zend_Http_Client();
       
                      $client->setUri('https://personalize.rapleaf.com/v4/dr?api_key=' . $api_key .
                                      '&email=' . urlencode($customer->getEmail()) .
                                      '&first=' . urlencode($customer->getFirstname()) .
                                      '&last=' . urlencode($customer->getLastname())
                      );
       
                      $client->setConfig(array('maxredirects' => 0, 'timeout' => 2));
       
                      $response = $client->request();
       
                      if ($response->getStatus() < 200 || $response->getStatus() >= 300)
                      {
                          Mage::log(
                              sprintf("Rapleaf query failed. (status: %s), (message: %s)",
                                  $response->getStatus(),
                                  strip_tags($response->getBody())),
                              null,
                              'rapleaf_api.log',
                              false);
                      }
                      else
                      {
                          $data = json_decode($response->getBody(), true);
                          if(array_key_exists('gender', $data))
                          {
                              $customer->setGender(
                                  Mage::getResourceSingleton('customer/customer')
                                      ->getAttribute('gender')
                                      ->getSource()
                                      ->getOptionId($data['gender'])
                              );
                          }
                      }
                  }
                  catch (Exception $e)
                  {
                      Mage::log(
                          sprintf("Exception in Rapleaf query. (message: %s)",
                             strip_tags($e->getMessage())),
                          null,
                          'rapleaf_api.log',
                          false);
                  }
              }
          }
      }

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 08 Oct 2015 13:16:59 +0000
      <![CDATA[为你的Magento项目创建Windows虚拟主机]]> https://www.360magento.com/blog/vhosts-for-ymagento/ 这篇文章是为那些准备或者刚刚开始网站开发冒险的初学者而写的。这不是唯一一种管理你本地环境的方式,但是是比较好的一种。

      如果长期在一个本地Windows机器上开发Magento项目,你会注意到很严重的性能下降。这是因为Magento是一个有很多小文件和大量数据表/项的巨大系统。例如,最新的Magento CE有11900多个文件,默认有4435个以上的文件夹(不包含SVN文件,如果你必须用它或者没意识到git的优势)。将其乘以一打项目(活跃的和处于支持状态的),你就会有严重的碎片问题。SSD磁盘是不错,但就个人而言,我觉得这并不是一个可靠的解决方案。

      创建Windows虚拟主机

      在一个独立的分区里为你正在开发的Magento项目创建虚拟主机。使用分区还有个好处:在系统故障时有更高的可能性恢复数据。(墨菲定律:没有被版本控制系统跟踪的重要文件会先丢失)。下面是步骤:

      1.用你喜欢的分区工具创建一个新的分区。使它的大小比你预估的项目大小大两倍(如果使用SVN就大三倍)。创建一个新文件夹来保留你的Magento项目(例如,X:\yourmagentoproject\)

      2.关闭Apache服务并显示Windows隐藏文件。

      3.以管理员身份打来你最喜欢的文本编辑工具。记事本就可以完成这个工作。如果你不知道怎么做,即便有管理员权限也不会自动拥有所有文件的编辑权限。使用Windows搜索找到记事本,在右键菜单中选择“以管理员身份运行”。

      4.用文本编辑器打开hosts文件(默认在"Windows\System32\drivers\etc\"),在文件的最后添加新的域名

      127.0.0.1 yourmagentoproject.loc

      5.打开Apache的主要配置文件httpd.conf。默认在Apache安装目录的conf文件夹内。找到下面一行

      # This should be changed to whatever you set DocumentRoot to.

      这是定义默认文件目录的块。添加下面的代码:

      <Directory "X:/yourmagentoproject/">
         Options Indexes FollowSymLinks
         AllowOverride All
         Order Deny,Allow
         Allow from all
      
      

      6.打开Apache虚拟主机配置文件,一般在Apache文件的\extra\httpd-vhosts.conf,在文件最后添加下面的代码:

      	DocumentRoot "X:/yourmagentoproject/"
      	ServerName yourmagentoproject.loc
      	ServerAlias yourmagentoproject.loc
      	DirectoryIndex index.php index.html index.htm not-a-file
      
      

      如果你想知道……是的,目录索引在虚拟主机文件中被定义。

      移动MySQL数据文件到独立分区

      Magento数据库中有大量的表,每张表都存储在对应的.frm文件放置在一个以数据库命名的文件夹里。你在Magento后台对数据进行的增删改查操作都会跟前端访问日志,统计信息一起保存在数据库中。当一个已经存在的网站不再被需要或是要被替换时,你还得处理客户数据库。那么就有很多的文件管理任务等着你的磁盘来处理。这意味着大量的文件碎片随着时间堆积起来。

      将MySQL数据文件移到一个独立分区的步骤:

      1.为你的MySQL数据文件创建一个独立的分区。记得要能满足你的数据库大小需求。

      2.关闭MySQL服务

      3.找到你的MySQL数据文件,默认在你MySQL安装目录的data文件夹里。拷贝整个文件夹到你新分区里。新的路径应该看起来是这样:Y:\data\。打开my.ini文件,添加或者修改下面的代码:

      #Path to the database root
      datadir="Y:/data/"

      以及

      #*** INNODB Specific options ***
      innodb_data_home_dir="Y:/data/"

      4.开启MySQL服务。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 08 Oct 2015 13:07:42 +0000
      <![CDATA[选择Magento的十大理由]]> https://www.360magento.com/blog/top-10-magento/ 自Magento发布以来,因其作为电商平台展现出的强大受到了开发人员和商人的极大关注。开发人员喜欢它的模块化,因为他们可以利用模块化几乎完成客户的所有需求。商人则喜欢它提供的多种多样的功能。

      下面我总结了下,选择Magento的十大理由:

      1. SEO友好:搜索引擎友好,Google站地图,产品,类别和内容的meta信息,等等……
      2. 国际化支持:支持本地化,多货币和税率。支持重音符号和从右到左文字。允许针对某些国家的配置。欧盟增值税ID验证,欧盟cookie通知,等等……
      3. 内置大量电商相关功能(相比其它任何PHP开源竞争对手):支持多站点和多域名设置。你可以在http://www.magentocommerce.com/images/uploads/magento-feature-list.pdf下载功能列表。
      4. 高度模块化设计:使得前端(布局和模版)和后端(事件,观察者,重写,网格等..)的深度定制成为可能。
      5. Magento专家咨询小组(不是免费服务,但是对于需要的人来说还是很重要的):官方培训&专业认证开发:为后端开发人员,前端开发人员和商家等培训。Magento认证工程师,Magento认证高级工程师,Magento认证目录(搜集全球Magento认证工程师)
      6. 安全:Magento高度重视安全并给予高优先级。Magento EE(企业版)更是提供为安全支付桥提供PCI数据安全标准(PCI PA-DSS)。
      7. Magento的连接:世界上最大的电子商务应用市场。
      8. 开源:让你可以玩转PHP代码。
      9. Web服务API:内置支持SOAP v1, SOAP v2, XMLRPC,REST with 3-legged OAuth 1.0a.
      10. 因为它真的很棒 :)

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 07 Oct 2015 15:57:23 +0000
      <![CDATA[跟踪Magento“添加产品到购物车”动作]]> https://www.360magento.com/blog/tracking-magento-addtocart/ 最近,我一直在忙一个关于第三方客户分析和定位服务的插件,考虑替换Google分析。其中一个要被实现的电商追踪功能是“添加产品到购物车”动作。由于这种追踪服务是使用JavaScript来触发它们的追踪代码,在Magento中何时何地嵌套追踪JavaScript是由我们决定的。有趣的是,“添加产品到购物车”动作不是你想执行JavaScript就执行的普通页面。

      在Magento中,当你点击任何“添加产品到购物车”页面,通常会以像http://magentoce1800.loc/index.php/checkout/cart/add/uenc/aHR0…0bWw,/product/16/form_key/oTSbNJ4ZIUC46W0R/的链接结束。其中checkout/cart/add是最有趣的一部分,由于它指向Mage_Checkout模型,它的CartController和对应的addAction()。第二个有趣的部分是product/16,它告诉Magento,ID为16的产品被添加到了购物车。此外,addAction()方法里进行了很多事情。比较重要,需要你记住的是:当Magento中addAction()方法添加产品到购物车的时候,它指向它本身的购物车页面。也就是说,实际的checkout/cart/add页面从不呈现在浏览器,所以你无法在这个页面是执行任何JavaScript。

      那么,我们要从哪里开始呢?好了,Magento一个比较炫酷的功能就是定义它的事件/监听系统。如果你仔细想想,每一个控制器动作支持controller_action_predispatch事件(定义在app/code/core/Mage/Core/Controller/Varien/Action.php 527行左右)。之后一些具体的时间匹配到它的模块前端名,控制器和动作。在这里,解析为前端事件controller_action_predispatch_checkout_cart_add

      考虑到这一点,这里有了个通过JavaScript追踪“添加产品到购物车”行动的简单想法。

      1. 为定义controller_action_predispatch_checkout_cart_add事件定义事件监听方法;
      2. 在事件监听方法中,当添加产品到购物车时做个记录。例如Mage::getModel(‘core/session’)->setProductToShoppingCart(…)这样的东西。
      3. 写个布局更新checkout_cart_index句柄,读取一个自定义的.phtml模版文件,你可以用core/template或者你自己的模块类来定义块的类型。
      4. 在自定义的.phtml文件中使用Mage::getModel(‘core/session’)->getProductToShoppingCart()来生成你的“添加产品到购物车”追踪点,获取刚刚添加到购物车的产品的信息。在完成这些之后,使用Mage::getModel(‘core/session’)->unsProductToShoppingCart()清除session。

      下面是代码示例:

      第一步中描述的 app/code/community/Alwayly/Test/etc/config.xml

      <?xml version="1.0"?>
       
      <config>
          <modules>
              <Alwayly_Test>
                  <version>1.0.0.0</version>
              </Alwayly_Test>
          </modules>
          <<global>
              <models>
                  <alwayly_test>
                      <class>Alwayly_Test_Model</class>
                  </alwayly_test>
              </models>
          </global>
          <frontend>
              <layout>
                  <updates>
                      <alwayly_test>
                          <file>alwayly_test.xml</file>
                      </alwayly_test>
                  </updates>
              </layout>
              <events>
                  <controller_action_predispatch_checkout_cart_add>
                      <observers>
                          <alwayly_test_log_cart_add>
                              <class>alwayly_test/observer</class>
                              <method>logCartAdd</method>
                          </alwayly_test_log_cart_add>
                      </observers>
                  </controller_action_predispatch_checkout_cart_add>
              </events>
          </frontend>
      </config>
      

      第二步中描述的:app/code/community/Alwayly/Test/Model/Observer.php

      <?php
       
      class Alwayly_Test_Model_Observer
      {
          public function logCartAdd() {
       
              $product = Mage::getModel('catalog/product')
                              ->load(Mage::app()->getRequest()->getParam('product', 0));
       
              if (!$product->getId()) {
                  return;
              }
       
              $categories = $product->getCategoryIds();
       
              Mage::getModel('core/session')->setProductToShoppingCart(
                  new Varien_Object(array(
                      'id' => $product->getId(),
                      'qty' => Mage::app()->getRequest()->getParam('qty', 1),
                      'name' => $product->getName(),
                      'price' => $product->getPrice(),
                      'category_name' => Mage::getModel('catalog/category')->load($categories[0])->getName(),
                  ))
              );
          }
      }
      

      很显然,上面的代码比较基础。不包括Magento各种产品类型,因为它直接从产品模块获取产品价格。所以,当有捆绑或者批量销售产品时,你需要做一点扩展。你可以用产品id引到产品表,以此来找到子产品。

      第三步所描述的:app/design/frontend/default/default/layout/alwayly_test.xml

      <?xml version="1.0"?>
       
      <layout version="0.1.0">
          <checkout_cart_index>
              <reference name="before_body_end">
                  <block type="alwayly_test/event_checkout_cart_index" name="alwayly_test_event_checkout_cart_index" template="alwayly/test/event/checkout/cart/index.phtml" />
              </reference>
          </checkout_cart_index>
      </layout>

      第四部所描述的:app/design/frontend/default/default/template/alwayly/test/event/checkout/cart/index.phtml

      <?php $_product = Mage::getModel('core/session')->getProductToShoppingCart() ?>
      <getId()): ?>
          <<script type="text/javascript">
              //Some 3rd party JS tracking code
          </script>
          <?php Mage::getModel('core/session')->unsProductToShoppingCart(); ?>
      <?php endif; ?>
      

      这就是一个简单的为你的分析服务追踪“添加产品到购物车”动作的方式。

      好处是:你不需要更改已有的.phtml文件增加JS点击事件或者类似的事情。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 07 Oct 2015 15:51:59 +0000
      <![CDATA[Magento允许的最大订单金额]]> https://www.360magento.com/blog/magento-maximumr-amount/ 最近我在做的一个项目中,有一个小的防欺诈功能。这个功能就是允许的最大订单金额。也许一开始听起来很奇怪,怎么会有人想限制订单的最大金额呢?鉴于该商店销售产品的性质(这里不能透露),这个功能要求似乎很合理。如果你看下Magento后台管理,你会在System > Configuration > Sales > Sales > Minimum Order Amount看到与它相反的功能。

      最小订单金额功能和我们最大订单金额略有不同。最大的区别就是,你无法添加超出金额的商品到购物车。那么我们该如何做呢?答案很简单事件/监听(event/observer)系统。我们所要做的是找到相对应的时间并挂钩一个观测者。经过仔细追查,一些尝试和失败以后,最合乎逻辑的事件似乎是:sales_quote_save_before。此外,只实现最大订单金额功能在前端是有道理的,因为我们不希望限制管理员创建订单。考虑到这一点,我们只需要添加以下代码到我们扩展的config.xml文件中:

      <config>
          <frontend>
              <events>
                  <sales_quote_save_before> 
                      <observers>
                          <alwayly_maxorderamount_enforceSingleOrderLimit>
                              <class>alwayly_maxorderamount/observer</class>
                              <method>enforceSingleOrderLimit</method>
                          </alwayly_maxorderamount_enforceSingleOrderLimit>
                     </observers>
                  </sales_quote_save_before>
              </events>
          </frontend>
      <config>
      

      创建我们Observer.php,在类中添加逻辑:

      class Alwayly_MaxOrderAmount_Model_Observer
      {
          private $_helper;
       
          public function __construct() 
          {
              $this->_helper = Mage::helper('alwayly_maxorderamount');
          }
       
          /**
           * No single order can be placed over the amount of X
           */
          public function enforceSingleOrderLimit($observer)
          {
              if (!$this->_helper->isModuleEnabled()) {
                  return;
              }
       
              $quote = $observer->getEvent()->getQuote();
       
              if ((float)$quote->getGrandTotal() > (float)$this->_helper->getSingleOrderTopAmount()) {
       
                  $formattedPrice = Mage::helper('core')->currency($this->_helper->getSingleOrderTopAmount(), true, false);
       
                  Mage::getSingleton('checkout/session')->addError(
                      $this->_helper->__($this->_helper->getSingleOrderTopAmountMsg(), $formattedPrice));
       
                  Mage::app()->getFrontController()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'));
                  Mage::app()->getResponse()->sendResponse();
                  exit;
              }
          }
      }
      

      这个方法的实现在代码的“Mage::getSingleton(‘checkout/session’)->addError() …”这行。这里触发sales_quote_save_before事件,当新添加的商品超过最大订单金额时,Magento不更新购物车。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 06 Oct 2015 13:09:31 +0000
      <![CDATA[重写Magento块,模型,助手和控制器]]> https://www.360magento.com/blog/overriding-magento/ 没有一个项目是使用原有的框架,都是时不时地要修改些东西。增加新的东西或者重写已经写好的东西。由于很多原因,修改核心文件是一个坏习惯,不被推荐。因此,Magento带来一种很好的方式来重写/覆盖这些文件。

      我们已经写过如何重写Magento模型类,但需要修改助手,块和控制器,不论是前端还是后台。

      重写Magento块

      让我们以重写核心标签块开始。假设要对Mage_Tag_Block_Product_List类做些改变。我们要做的是在这个类的基础上添加我们自己的文件来扩展它。所有要做的就是添加下面的代码到当前模块的config.xml文件中。

      <config>
          <global>
              <blocks>
                  <tag>
                     <rewrite>
                          <product_list>Alwayly_Tag_Block_Product_List</product_list>
                      </rewrite>
                 </tag>
              </blocks>
          </global>
      </config>
      

      由类名可以得出,文件要被创建在app/code/local/Alwayly/Tag/Block/Product/List.php,其中要定义类:

      class Alwayly_Tag_Block_Product_List extends Mage_Tag_Block_Product_List
      {
      // some code
      }
      

      等效于上面的例子,同样的规则可以应用在aminhtml中,当我们想要重写Mage_Adminhtml_Block_Tag_Edit类时。

      <config>
          <global>
             <blocks>
                  <adminhtml>
                      <rewrite>
                          <tag_edit>Alwayly_Tag_Block_Adminhtml_Tag_Edit</tag_edit>
                      </rewrite>
                  </adminhtml>
              </blocks>
          </global>
      </config>
      

      那么需要创建app/code/local/Alwayly/Tag/Block/Adminhtml/Tag/Edit.php,在文件中写下类的代码:

      class Alwayly_Tag_Block_Adminhtml_Tag_Edit extends Mage_Adminhtml_Block_Tag_Edit
      {
      // some code
      }
      

      重写Magento助手

      按照同样的规则,Magento助手也可以轻松地被重写。config.xml中的代码:

      <config>
          <global>
              <helpers>
                  <tag>
                      <rewrite>
                         <data>Alwayly_Tag_Helper_Data</data>
                     </rewrite>
                  </tag>
              </helpers>
          </global>
      </config>
      

      创建app/code/local/Alwayly/Tag/Helper/Data.php文件并定义类:

      class Alwayly_Tag_Helper_Data extends Mage_Tag_Helper_Data
      {
      // some code
      }
      

      重写Magento模型

      我们已经重写过Magento模型,但是资源文件和集合文件呢?和核心模型文件一样,资源和集合文件的重写和其它文件一样。文件将扩展:

      • Mage_Tag_Model_Tag
      • Mage_Tag_Model_Resource_Tag

      Config.xml代码:

      <config>
          <global>
              <models>
                  <tag>
                      <rewrite>
                          <!-- Model -->
                          <tag>Alwayly_Tag_Model_Tag</tag>
                      </rewrite>
                  </tag>
                  <tag_resource>
                     <rewrite>
                          <!-- Resource -->
                          <tag>Alwayly_Tag_Model_Resource_Tag</tag>
                          <!-- Collection -->
                          <tag_collection>Alwayly_Tag_Model_Resource_Tag_Collection</tag_collection>
                      </rewrite>
                  </tag_resource>
              </models>
          </global>
      </config>
      

      接着,创建下面这些文件:

      • app/code/local/Alwayly/Tag/Model/Tag.php
      • app/code/local/Alwayly/Tag/Model/Resource/Tag.php
      • app/code/local/Alwayly/Tag/Model/Resource/Tag/Collection.php.

      注意:这里只是个示例,在你的项目里只重写你需要的类。

      重写Magento控制器

      重写控制器比上面的示例要难一点,和我们之前例子中看到的Magento重写规则不一样。那如何重写Mage_Tag控制器呢?让我们看看代码吧。在config.xml中:

      <config>
          <frontend>
              <routers>
                 <tag>
                      <args>
                          <modules>
                              <alwayly_tag before="Mage_Tag">Alwayly_Tag</alwayly_tag>
                          </modules>
                      </args>
                  </tag>
              </routers>
          </frontend>
      </config>
      

      在配置结点的孩子定义我们是否正在改变前端或者管理文件。我们定义的路由器结点将用它的参数重写核心标签模型。在底部结点出现当前模块前端的域名(alwayly_tag)和我们的模块名(Alwayly_Tag)。

      你注意到,这里没有严格定义的文件。这样我们需要由控制器名定义这个路径下的文件。如果我们要重写app/code/core/Mage/Tag/controllers/TagController.php,那么具有相同名称的文件将被创建在app/code/local/Alwayly/Tag/controllers/TagController.php

      在新文件中定义类:

      require_once(Mage::getModuleDir('controllers','Mage_Tag').DS.'TagController.php');
       
      class Alwayly_Tag_TagController extends Mage_Tag_TagController
      {
      // some code
      }
      

      类似地,要修改后台控制器的话。Config.xml代码:

      <config>
          <admin>
              <routers>
                  <adminhtml>
                      <args>
                          <modules>
                              <alwayly_tag before="Mage_Adminhtml">Alwayly_Tag_Adminhtml</alwayly_tag>
                          </modules>
                      </args>
                  </adminhtml>
              </routers>
          </admin>
      </config>
      

      创建app/code/local/Alwayly/Tag/controllers/Adminhtml/TagController.php文件并定义类:

      require_once(Mage::getModuleDir('controllers','Mage_Adminhtml').DS.'TagController.php');
       
      class Alwayly_Tag_Adminhtml_TagController extends Mage_Adminhtml_TagController
      {
      // some code
      }
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 06 Oct 2015 13:05:06 +0000
      <![CDATA[对Magento进行shell语言]]> https://www.360magento.com/blog/php-shell-magento/ 有时候我们需要从Magento外部访问Magento系统。一种方式是使用PHP shell语言引导Magento。一个普通PHP开发者会在自己代码的底部创建一个引导文件来访问Magento根目录。如你猜测的一样,有两种引导Magento的方式,常用方式和Magento方式。在这篇文章中,我们将概述如何以Magento的方式创建PHP shell脚本来引导Magento。

      对于初学者来说,这里是引导Magento的常规方法(Magento中index.php中使用的):

      require_once 'app/Mage.php';
      Mage::app();
       
      // Our own code goes here
      

      虽然这种方法没有错误,但是和Magento方式相比有些不足。

      The Magento way

      现在,让我们看看用Magento方式来实现。如果你访问Magento根目录下shell文件夹,你会发现一些"Magento方式的"shell语言。比如,你有index.php可以使用所选的索引来重建索引,或者compiler.php去控制Magento编译器功能状态。如果你看了PHP shell脚本,你会看到在abstract.php文件包含Mage_Shell_Abstract类和其所包含、扩展Mage_Shell_Abstract类。

      有些人想知道这样比单纯请求Mage.php好在哪。特别是当你看到Mage_Shell_Abstract结构体后,发现做的同样的事情。

      使用Magento方式的有点之一是Mage_Shell_Abstract类提供解析命令行参数。第二,Mage_Shell_Abstract结构体会调用Mage_Shell_Abstract::__applyPhpVariables() function函数来解析.htaccess文件并应用php设置到shell脚本。

      执行过程很明显。我将粘贴出Magento PHP shell脚本的骨架类:

      <?php
      require_once 'abstract.php';
       
      class Inchoo_Shell_Myscript extends Mage_Shell_Abstract
      {
          protected $_argname = array();
       
          public function __construct() {
              parent::__construct();
       
              // Time limit to infinity
              set_time_limit(0);     
       
              // Get command line argument named "argname"
              // Accepts multiple values (comma separated)
              if($this->getArg('argname')) {
                  $this->_argname = array_merge(
                      $this->_argname,
                      array_map(
                          'trim',
                          explode(',', $this->getArg('argname'))
                      )
                  );
              }
          }
       
          // Shell script point of entry
          public function run() {
       
          }
       
          // Usage instructions
          public function usageHelp()
          {
              return <<       Argument description
       
        help                   This help
       
      USAGE;
          }
      }
      // Instantiate
      $shell = new Inchoo_Shell_Myscript();
       
      // Initiate script
      $shell->run();
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 05 Oct 2015 01:50:29 +0000
      <![CDATA[禁用Magento默认的通讯交易邮件]]> https://www.360magento.com/blog/disabling-newsletter-emails/ 并不是每个人对Magento中的通讯选项满意,所以他们选择第三方服务。在这种情况下,关闭Magento默认的通讯交易邮件并让第三方服务来接管电子邮件是一个好主意。在这篇文章中我将演示如何关闭Magento中默认的通讯交易邮件。

      首先,我们重写核心文件中的config.xml

      <newsletter>
      	<rewrite>
      		<subscriber>Alwayly_Newsletter_Model_Newsletter_Subscriber</subscriber>
      	</rewrite>
      </newsletter>
      

      创建system.xml,把下面的代码放进去:

      <?xml version="1.0"?>
       
      <config>
         <tabs>
              <alwayly_tab translate="label">
                  <label>Alwayly</label>
                  <sort_order>200</sort_order>
              </alwayly_tab>
          </tabs>
       
          <sections>
              <alwayly_newsletter translate="label">
                  <label>Newsletter Configuration</label>
                  <tab>alwayly_test_tab</tab>
                 <frontend_type>text</frontend_type>
                  <sort_order>1</sort_order>
                  <show_in_default>1</show_in_default>
                  <show_in_website>1</show_in_website>
                  <show_in_store>1</show_in_store>
                  <groups>
                      <newsletter_subscription_transactional_mails>
                         <label>Newsletter Subscription Transactional Mails</label>
                          <frontend_type>text</frontend_type>
                          <show_in_default>1</show_in_default>
                          <show_in_website>1</show_in_website>
                          <show_in_store>1</show_in_store>
                          <sort_order>120</sort_order>
                          <fields>
                              <enabled translate="label">
                                 <label>Enable</label>
                                  <frontend_type>select</frontend_type>
                                  <source_model>adminhtml/system_config_source_yesno</source_model>
                                  <sort_order>40</sort_order>
                                  <show_in_default>1</show_in_default>
                                  <show_in_website>1</show_in_website>
                                  <show_in_store>1</show_in_store>
                              </enabled>
                          </fields>
                      </newsletter_subscription_transactional_mails>
                  </groups>
              </alwayly_newsletter>
          </sections>
      </config>
      

      下一步,我们将添加我们的配置路径到Helper类和一个获取值的方法:

      class Alwayly_Newsletter_Helper_Data extends Mage_Core_Helper_Abstract
      {
          const XML_PATH_NEWSLETTER_MAILS  = 'alwayly_newsletter/newsletter_subscription_transactional_mails/enabled';
       
          public function getNewsletterSubscriptionMailEnabled()
          {
              return Mage::getStoreConfig(self::XML_PATH_NEWSLETTER_MAILS);
          }
      }
      

      最后一步就是编辑几个以前我们改写过的核心方法。我们新的模型类是Alwayly_Newsletter_Model_Newsletter_Subscriber,它扩展自Mage_Newsletter_Model_Subscriber类。类名取决于你的模块,我们经常要扩展核心类,否则将无法正常工作。

      你将需要从核心类里拷贝3个方法到我们的新类中并做一些调整。

      • 公用方法subscribe($email)
      • 公用方法subscribeCustomer($customer)
      • 公用方法unsubscribe()

      在subscribe方法中找到:

      if ($isConfirmNeed === true
      	&& $isOwnSubscribes === false
      ) {
      	$this->sendConfirmationRequestEmail();
      } else {
      	$this->sendConfirmationSuccessEmail();
      }
      

      用下面的代码替换:

      if ((bool) Mage::helper('alwayly_newsletter')->getNewsletterSubscriptionMailEnabled()) {
          if ($isConfirmNeed === true && $isOwnSubscribes === false) {
              $this->sendConfirmationRequestEmail();
          } else {
              $this->sendConfirmationSuccessEmail();
          }
      }
      

      在subscribeCustomer方法中找到:

      if ($this->getIsStatusChanged() && $status == self::STATUS_UNSUBSCRIBED) {
          $this->sendUnsubscriptionEmail();
      } elseif ($this->getIsStatusChanged() && $status == self::STATUS_SUBSCRIBED) {
          $this->sendConfirmationSuccessEmail();
      }
      

      替换成:

      if ((bool) Mage::helper('alwayly_newsletter')->getNewsletterSubscriptionMailEnabled()) {
          if ($this->getIsStatusChanged() && $status == self::STATUS_UNSUBSCRIBED) {
              $this->sendUnsubscriptionEmail();
          } elseif ($this->getIsStatusChanged() && $status == self::STATUS_SUBSCRIBED) {
              $this->sendConfirmationSuccessEmail();
          }
      }
      

      最后一个unsubscribe方法中:

      $this->sendUnsubscriptionEmail();
      

      替换为:

      if ((bool) Mage::helper('alwayly_newsletter')->getNewsletterSubscriptionMailEnabled()) {
          $this->sendUnsubscriptionEmail();
      }
      

      这意味着,我们首先检查我们的配置选项设置为启用或禁用。如果设置为禁用则不执行if语句里的代码。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 05 Oct 2015 01:36:14 +0000
      <![CDATA[Magento配置计划任务]]> https://www.360magento.com/blog/magento-configurable-cron/ Magento中的计划任务很容易配置。config.xml中的几行代码加一个方法就完成了。但如果你想更有意思点,创建一个日程计划任务呢?幸运的是,Magento系统中已经有了这个功能,实现起来也很简单。

      计划任务本身比较直接。正如下面代码所见,它在config.xml中由两部分被定义:日程和一个被执行的方法。下面的例子展示了一个名为"my_cron"的计划任务,每5分钟执行观测者文件中的"doSomething"方法。如果你不熟悉计划任务的格式,网上有一堆关于计划任务的文章。

      <config>
          <crontab>
              <jobs>
                  <my_cron>
                      <schedule>
                          <cron_expr>*/5 * * * *</cron_expr>
                     </schedule>
                      <run>
                          <model>mymodule/observer::doSomething</model>
                      </run>
                  </my_cron>
              </jobs>
         </crontab>
      </config>
      

      计划任务不能被配置。在计划任务被生成的Mage_Cron_Model_Observer类里,有一个生成方法,以同样的方式检查core_config_data表中的值和configxml文件。知道了这一点,我们就可以保存路径和设置我们想要的值。让我们开始吧。

      Admin configuration(管理员配置)

      因为我们想要日程配置计划任务,所以我们需要有一个对应的管理员配置。你可以随你喜欢地完成它,但是我将使用Magento中提供给我们的。

      system.xml中会有Magento中封装好的时间(小时,分钟和秒)和频率选择器(每日,每周和每月)。代码所要完成的是创建我们的后台块来格式化和保存我们想要的路径值。在这里,它将在mymodule/adminhtml_system_config_backend_mymodel_cron

      <config>
          <sections>
              <catalog>
                <groups>
                      <configurable_cron translate="label">
                          <label>Cron Schedule</label>
                          <sort_order>100</sort_order>
                          <show_in_default>1</show_in_default>
                          <show_in_website>0</show_in_website>
                          <show_in_store>0</show_in_store>
                          <fields>
                              <time translate="label">
                                  <label>Start Time</label>
                                  <frontend_type>time</frontend_type>
                                  <sort_order>10</sort_order>
                                  <show_in_default>1</show_in_default>
                                 <show_in_website>0</show_in_website>
                                  <show_in_store>0</show_in_store>
                              </time>
                              <frequency translate="label">
                                  <label>Frequency</label>
                                  <frontend_type>select</frontend_type>
                                  <source_model>adminhtml/system_config_source_cron_frequency</source_model>
                                  <backend_model>mymodule/adminhtml_system_config_backend_mymodel_cron</backend_model>
                                  <sort_order>20</sort_order>
                                  <show_in_default>1</show_in_default>
                                  <show_in_website>0</show_in_website>
                                  <show_in_store>0</show_in_store>
                              </frequency>
                          </fields>
                      </configurable_cron>
                  </groups>
              </catalog>
          </sections>
      </config>
      

      Backend model(后台模块)

      管理员配置中的前端类型不保存计划任务选择器读取的输入类型。由于这个,我们必须后台模块来填补我们想要的输入类型。

      从上面设置普通计划任务的示例代码中,同样的路径也被core_config_data表使用,我们将要处理它。由上面的代码可知,我们日程的路径是"crontab/jobs/my_cron/schedule/cron_expr"。下面的代码格式化输入并保存值到表。

      class Alwayly_MyModule_Model_Adminhtml_System_Config_Backend_MyModel_Cron extends Mage_Core_Model_Config_Data
      {
          const CRON_STRING_PATH = ‘crontab/jobs/my_cron/schedule/cron_expr';
       
          protected function _afterSave()
          {
              $time = $this->getData('groups/configurable_cron/fields/time/value');
       
              $frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
              $frequencyWeekly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_WEEKLY;
              $frequencyMonthly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_MONTHLY;
       
              $cronDayOfWeek = date('N');
       
              $cronExprArray = array(
                  intval($time[1]),                                   # Minute
                  intval($time[0]),                                   # Hour
                  (frequency == $frequencyMonthly) ? '1' : '*',       # Day of the Month
                  '*',                                                # Month of the Year
                  (frequency == $frequencyWeekly) ? '1' : '*',        # Day of the Week
              );
              $cronExprString = join(' ', $cronExprArray);
       
              try {
                  Mage::getModel('core/config_data')
                      ->load(self::CRON_STRING_PATH, 'path')
                      ->setValue($cronExprString)
                      ->setPath(self::CRON_STRING_PATH)
                      ->save();
              }
              catch (Exception $e) {
                  throw new Exception(Mage::helper('cron')->__('Unable to save the cron expression.'));
       
              }
          }
      }
      

      计划任务生成器浏览计划任务,选择日程被定义的那个。从config表中读取日程,日程调度结点必须从config.xml中被移除,仅定义了模型,如下所示:

      
      <config>
          <crontab>
              <jobs>
                  <my_cron>
                      <run>
                          <model>mymodule/observer::doSomething</model>
                      </run>
                  </my_cron>
              </jobs>
          </crontab>
      </config>
      

      后台发生了什么?计划任务生成器浏览config.xml文件和config表,寻找计划任务日程并填充计划日程表。此时和模型是不相关的。没有被定义日程的计划任务被跳过。另一种方法,从计划日程表中读取计划任务,从config.xml文件和config表中收集方法并执行。

      Observer(观测者)

      观测者中是将被计划任务执行的方法。这里的代码由你决定。

      
      class Alwayly_MyModule_Model_Observer
      {
          public function doSomething()
          {
      	// do something
          }
      }
      

      这只是个使用日程计划任务的例子。当你理解它如何工作后,这里还有很大的提升空间。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 04 Oct 2015 11:31:05 +0000
      <![CDATA[根据多个ID筛选订单网格]]> https://www.360magento.com/blog/filter-order-ids/ 我们都知道Magento的网格很棒,是有效显示数据的不二选择。

      我们的客户在选择Magento后有时(基本是经常)会有些特殊的需求。其中有人提出通过订单ID来过滤订单网格。

      当你有大批订单要跟踪的时候就显得很有用了。一个一个筛选是个繁琐而又耗时的任务。

      我要告诉你的诀窍可以处理几乎所有的网格,只要你知道它是如何做的。

      首先,重写你的订单网格块(app\code\core\Mage\Adminhtml\Block\Sales\Order\Grid.php)——我想你知道怎么做。

      在你的 _prepareColumns() 方法里,向数组里添加一个元素,如下:

      protected function _prepareColumns()
      {
      	$this->addColumn('real_order_id', array(
      		'header'=> Mage::helper('sales')->__('Order #'),
      		'width' => '250px',
      		'type'  => 'text',
      		'index' => 'increment_id',
      		'filter_condition_callback' => array($this, 'spaceSeparatedFilter')//calling spaceSeparatedFilter method
      	));
      ....
      }
      

      在我们网格中一行被渲染时,渲染器被调用。通过cell被渲染成一个字段。过滤器回调,另一方面,调用整个列和集合作为字段。结果是,我们可以创建自己的方法,调用变量filter_condition_callback元素,向数据库执行自定义查询语句,获取我们网格中的输入框等等……

      这正是我们要做的……

      我们的过滤器回调将调用spaceSeparatedFilter()方法并把real_order_id列作为一个参数。让我们声明我们的方法(在Grid.php文件中):

      protected function spaceSeparatedFilter($collection, $column)
      {
      	if (!$value = $column->getFilter()->getValue()) {
      		return $this;
      	}
      	//if there was a space input
      		else if(preg_match('/\s+/', $value))
      	{
      		//explode by space, getting array of IDs
      		$val = explode(" ", $value);
      		//filter the collection, where collection index (order_id) is present in $val array
      		$this->getCollection()->addAttributeToFilter($column->getData('index'), array('in'=>$val));
      	}
      	else
      	{
      	//else use default grid filter functionality (like $value input)
      	$this->getCollection()->addAttributeToFilter($column->getData('index'), array('like' => '%'.$value.'%'));
      	}
      	return $this;
      }
      

      这两段代码可以让你通过多个订单ID来过滤订单,只要你用空间将他们分开。如果你没有进入一个空间,那么会按默认的工作。

      你也可以使用网格的所有功能:排序,筛选,导出。没有任何问题。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 04 Oct 2015 11:18:09 +0000
      <![CDATA[在Magento中用getModel和getData方法来获取东西]]> https://www.360magento.com/blog/magento-getmodel-getdata/ 如果你正在Magento中开发,迟早有一天你会需要从数据库中获取信息。这篇文章将会给你展示用getModel,getData和getter方法获取几乎任何东西。

      例如:假设你正在尝试找出产品名字,描述和价格。首先你要做的就是获取产品模型:

      $productModel = Mage::getModel('catalog/product');

      通过调用getModel('catalog/product'),你将Mage_Catalog_Model_Product类(定义在app/code/core/Mage/Catalog/Model/Product.php)实例化。但是Magento如何知道这个类在哪呢?

      参数‘catalog/product’的第一部分来自模块配置,通常和模块文件夹名一样。如果你看了app/code/core/Mage/Catalog/etc/config.xml文件,你将会看到:

      <config>
          …
          <global>
              <models>
                  <catalog>
                      <class>Mage_Catalog_Model</class>
                      …
                  </catalog>
                  …
              </models>
              …
          </global>
          …
      </config>
      

      从这里,你可以看到,所有名字以Mage_Catalog_Model开始的模块都被定义在Model文件夹下。参数‘catalog/product’的第二部分告诉Magento定义类的文件。在这里,是Product.php。

      现在,我们有了对的模型,下一步就是告诉我们的模块,哪个产品要被读取。用load($id)方法很容易实现。

      $product = $productModel->load(42);

      注意,这里的42只是个id的例子,应该被你需要读取的产品id替换。

      在读取我们的产品之后,这里有两种方法从对象里读取数据。

      $name = $product->getName(); // same as $product->getData('name');
      $description = $product->getData('description'); // same as $product->getDescription();
      

      两种方法都很好。但是当读取价格时就有点不一样了。

      $price = $product->getPrice(); // same as $product->getData('price');
      $finalPrice = $product->getFinalPrice();
      

      万一我们的产品在任何价格规则下,这两个变量就会有不一样的值。有什么不一样呢?$price变量会显示后台被你编辑过的产品原价。 $finalPrice变量在这里是经过价格规则处理后的价格。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 03 Oct 2015 07:55:41 +0000
      <![CDATA[Magento中的畅销产品]]> https://www.360magento.com/blog/bestseller-magento/ 畅销产品是一类人逛Magento商店时会询问和浏览的。默认安装就已经有畅销产品这个功能……但是需要在CMS页面定义一个静态块。我们打算把它提升一下。

      Magento已经使用了畅销产品的聚合,你可以在Admin->Reports->Products->Bestsellers下确认。得益于这个被聚合的数据,我们不再需要确认所有订单来知道哪件产品卖得最多。通过各种聚合数据,我们能够获取从开始或者特定时间最受欢迎的产品。

      有很多实现的方法。我找到对我最有用的就是每月畅销产品的集合。这个方法快速而且即使聚合表为空时也可以访问产品。

      class Alwayly_Luckcy_Block_Bestsellers extends Mage_Core_Block_Template
      {
          public function getBestsellerProducts()
          {
              $storeId = (int) Mage::app()->getStore()->getId();
       
              // Date
              $date = new Zend_Date();
              $toDate = $date->setDay(1)->getDate()->get('Y-MM-dd');
              $fromDate = $date->subMonth(1)->getDate()->get('Y-MM-dd');
       
              $collection = Mage::getResourceModel('catalog/product_collection')
                  ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
                  ->addStoreFilter()
                  ->addPriceData()
                  ->addTaxPercents()
                  ->addUrlRewrite()
                  ->setPageSize(6);
       
              $collection->getSelect()
                  ->joinLeft(
                      array('aggregation' => $collection->getResource()->getTable('sales/bestsellers_aggregated_monthly')),
                      "e.entity_id = aggregation.product_id AND aggregation.store_id={$storeId} AND aggregation.period BETWEEN '{$fromDate}' AND '{$toDate}'",
                      array('SUM(aggregation.qty_ordered) AS sold_quantity')
                  )
                  ->group('e.entity_id')
                  ->order(array('sold_quantity DESC', 'e.created_at'));
       
              Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
              Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
       
              return $collection;
          }
      }
      

      这段代码的作用是返回上月卖得最多的产品的集合。如果这个逻辑将是或者被使用超过一次,推荐将逻辑加入到分类产品集合文件(扩展这个文件或者使用事件)并在构建集合时作为方法来调用。现在,当产品集合准备好了,这里有更多的方法来将它们展示到前台。我们就以修改首页为例。后台进入CMS->Page,选择Identifier为'home'的那项。用下面的代码替代content。

      <div class="col-left side-col">
          <p class="home-callout"> 
          <p class="home-callout"><img src="{{skin url='images/ph_callout_left_rebel.jpg'}}" alt="" border="0" /></p>
          {{block type="tag/popular" template=“tag/popular.phtml"}}
      </div>
      <div class="home-spot">
          <p class="home-callout"><img src="{{skin url='images/home_main_callout.jpg'}}" alt="" width="470" border="0" /></p>
          <p class="home-callout"><img src="{{skin url='images/free_shipping_callout.jpg'}}" alt="" width="470" border="0" /></p>
          {{block type="damir/bestsellers" template=“luckcy/bestsellers.phtml"}}
      

      上面的代码包含了畅销产品块。最后一件事就是创建模版文件。模版文件使用了CMS页面同样的html结构:

      
      <div class="box best-selling">
      <h3>Best Selling Products</h3>
      <table border="0" cellspacing="0">
          <tbody>
          <?php $counter=0; foreach ($this->getBestsellerProducts() as $product): ?>
              <?php if ($counter%2 == 0): ?><tr class="<?php echo $counter%4 ? 'even' : 'odd'; ?>"><?php endif ?>
              <td>
                  <a href="<?php echo $product->getProductUrl() ?>"><img class="product-img" src="<?php echo $this->helper('catalog/image')->init($product, 'small_image')->resize(99); ?>" alt="<?php echo $this->stripTags($this->getImageLabel($product, 'small_image'), null, true) ?>" width="95" border="0" /></a>
                  <div class="product-description">
                      <p><a href="<?php echo $product--&gtgetProductUrl() ?>"><?php echo $this->stripTags($product->getName(), null, true); ?></a></p>
                  </div>
              </td>
              <?php if ($counter++%2): ?></tr><?php endif ?>
          <?php endforeach; ?>
          </tbody>
      </table>
      </div>
      

      这个例子使用的是每月聚合,我觉得是最实用的。这里也有每日聚合和每年聚合,但是使用得并不多。许多插件都有同样的功能,只是进行了些包装,最底层的逻辑都是一样的。

      由于强烈不推荐修改核心文件,所以每个项目必须至少有一个模型来放置自己的块。如果你对如何创建模块不熟悉,那么可以看看360magento.net中插件开发文章。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 03 Oct 2015 07:40:04 +0000
      <![CDATA[以编程的方式添加一个新的客户到Magento商店]]> https://www.360magento.com/blog/programmaticaly-customers-magento/ 我们程序员喜欢以编程的方式来添加东西。虽然你可以通过一个注册表单或者管理界面来创建一个新的客户。在某些情况下,这可能需要很长时间。如果你有一群来自不同国家的客户要分配给不同的群体,那你最好选择用代码来实现。

      首先,我们添加一个带有一些基础信息的客户。

      $websiteId = Mage::app()->getWebsite()->getId();
      $store = Mage::app()->getStore();
       
      $customer = Mage::getModel("customer/customer");
      $customer   ->setWebsiteId($websiteId)
                  ->setStore($store)
                  ->setFirstname('John')
                  ->setLastname('Doe')
                  ->setEmail('jd1@ex.com')
                  ->setPassword('somepassword');
       
      try{
          $customer->save();
      }
      catch (Exception $e) {
          Zend_Debug::dump($e->getMessage());
      }
      

      正如我们所见,上面的代码添加的用户只有姓、名、邮箱和密码。有时这些就够了,但我们可以做到更多。你可以添加中间名,把客户分配到特定的客户群,甚至给他们的名字加前缀或后缀。

      $customer   ->setWebsiteId($websiteId)
                  ->setStore($store)
                  ->setGroupId(2)
                  ->setPrefix('Sir')
                  ->setFirstname('John')
                  ->setMiddleName('2')
                  ->setLastname('Doe')
                  ->setSuffix('II')
                  ->setEmail('jd2@ex.com')
                  ->setPassword('somepassword');
      

      为了让客户能下订单,我们需要添加一个地址并分配给客户。让我们实现它吧。

      $address = Mage::getModel("customer/address");
      $address->setCustomerId($customer->getId())
              ->setFirstname($customer->getFirstname())
              ->setMiddleName($customer->getMiddlename())
              ->setLastname($customer->getLastname())
              ->setCountryId('HR')
      		//->setRegionId('1') //state/province, only needed if the country is USA
              ->setPostcode('31000')
              ->setCity('Osijek')
              ->setTelephone('0038511223344')
              ->setFax('0038511223355')
              ->setCompany('Inchoo')
              ->setStreet('Kersov')
              ->setIsDefaultBilling('1')
              ->setIsDefaultShipping('1')
              ->setSaveInAddressBook('1');
       
      try{
          $address->save();
      }
      catch (Exception $e) {
          Zend_Debug::dump($e->getMessage());
      }
      

      要注意的是,setCountryID需要国家代码来作为值(你可以在后台通过检索客户创建页面'Country'输入框来获值)。上面的setGroupId方法也一样,你需要获取客户群的ID。

      我希望大部分代码是不言自明的,由于我们从管理页面添加客户时知道哪些是必填项。唯一你要注意的就是必填项。

      万一你有多个用户要添加,你可以花几秒钟为这段代码添加一个循环。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 02 Oct 2015 10:57:54 +0000
      <![CDATA[Magento中以编程的方式创建捆绑产品]]> https://www.360magento.com/blog/programmatically-magento-bundle/ 如果说这是一个系列文章,那么这就是第三个了。如果你之前看过了Magento中简单产品和可配置产品的创建,那你已经了解了基础。

      这篇文章中我们将扩展知识,学习如何用编程的方式创建Magento的捆绑产品。

      捆绑产品就是你想要批量销售的产品。从图片中可能会让你有更好的了解。我们以Magento示例数据中的一个产品为例:

      magento在首页显示登陆注册框,创建magento下拉登陆框

      我们可以看到这个产品的每个自定义选项值都会对应一个捆绑相关的简单产品。例如,Camera选项有 Madison LX2200和Madison RX3400,它们对应不同的简单产品。现在我们跳过基础部分,我们将创建一个捆绑产品必要的两个选项,每一个选项有两个值来表示不同的产品。

      $bundleProduct = Mage::getModel('catalog/product');
          $bundleProduct
          ->setStoreId(Mage_Core_Model_App::ADMIN_STORE_ID) //you can set data in store scope
              ->setWebsiteIds(array(1)) //website ID the product is assigned to, as an array
              ->setAttributeSetId(20) //ID of a attribute set named 'default'
              ->setTypeId('bundle') //product type
              ->setCreatedAt(strtotime('now')) //product creation time
      //    ->setUpdatedAt(strtotime('now')) //product update time
              ->setSkuType(0) //SKU type (0 - dynamic, 1 - fixed)
              ->setSku('bundlexx1') //SKU
              ->setName('test bundle product96') //product name
              ->setWeightType(0) //weight type (0 - dynamic, 1 - fixed)
      //        ->setWeight(4.0000)
              ->setShipmentType(0) //shipment type (0 - together, 1 - separately)
              ->setStatus(1) //product status (1 - enabled, 2 - disabled)
              ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) //catalog and search visibility
              ->setManufacturer(28) //manufacturer id
              ->setColor(24)
              ->setNewsFromDate('06/26/2014') //product set as new from
              ->setNewsToDate('06/30/2014') //product set as new to
              ->setCountryOfManufacture('AF') //country of manufacture (2-letter country code)
              ->setPriceType(0) //price type (0 - dynamic, 1 - fixed)
              ->setPriceView(0) //price view (0 - price range, 1 - as low as)
              ->setSpecialPrice(00.44) //special price in form 11.22
              ->setSpecialFromDate('06/1/2014') //special price from (MM-DD-YYYY)
              ->setSpecialToDate('06/30/2014') //special price to (MM-DD-YYYY)
              /*only available if price type is 'fixed'*/
      //        ->setPrice(11.22) //price, works only if price type is fixed
      //        ->setCost(22.33) //price in form 11.22
      //        ->setMsrpEnabled(1) //enable MAP
      //        ->setMsrpDisplayActualPriceType(1) //display actual price (1 - on gesture, 2 - in cart, 3 - before order confirmation, 4 - use config)
      //        ->setMsrp(99.99) //Manufacturer's Suggested Retail Price
      //        ->setTaxClassId(4) //tax class (0 - none, 1 - default, 2 - taxable, 4 - shipping)
              /*only available if price type is 'fixed'*/
              ->setMetaTitle('test meta title 2')
              ->setMetaKeyword('test meta keyword 2')
              ->setMetaDescription('test meta description 2')
              ->setDescription('This is a long description')
              ->setShortDescription('This is a short description')
              ->setMediaGallery(array('images' => array(), 'values' => array())) //media gallery initialization
              ->setStockData(array(
                      'use_config_manage_stock' => 1, //'Use config settings' checkbox
                      'manage_stock' => 1, //manage stock
                      'is_in_stock' => 1, //Stock Availability
                  )
              )
              ->setCategoryIds(array(4, 10)); //assign product to categories
       
          $bundleOptions = array();
          $bundleOptions = array(
              '0' => array( //option id (0, 1, 2, etc)
                  'title' => 'item01', //option title
                  'option_id' => '',
                  'delete' => '',
                  'type' => 'select', //option type
                  'required' => '1', //is option required
                  'position' => '1' //option position
              ),
              '1' => array(
                  'title' => 'item02',
                  'option_id' => '',
                  'delete' => '',
                  'type' => 'multi',
                  'required' => '1',
                  'position' => '1'
              )
          );
       
          $bundleSelections = array();
          $bundleSelections = array(
              '0' => array( //option ID
                  '0' => array( //selection ID of the option (first product under this option (option ID) would have ID of 0, second an ID of 1, etc)
                      'product_id' => '554', //if of a product in selection
                      'delete' => '',
                      'selection_price_value' => '10',
                      'selection_price_type' => 0,
                      'selection_qty' => 1,
                      'selection_can_change_qty' => 0,
                      'position' => 0,
                      'is_default' => 1
                  ),
       
                  '1' => array(
                      'product_id' => '553',
                      'delete' => '',
                      'selection_price_value' => '10',
                      'selection_price_type' => 0,
                      'selection_qty' => 1,
                      'selection_can_change_qty' => 0,
                      'position' => 0,
                      'is_default' => 1
                  )
              ),
              '1' => array( //option ID
                  '0' => array(
                      'product_id' => '552',
                      'delete' => '',
                      'selection_price_value' => '10',
                      'selection_price_type' => 0,
                      'selection_qty' => 1,
                      'selection_can_change_qty' => 0,
                      'position' => 0,
                      'is_default' => 1
                  ),
       
                  '1' => array(
                      'product_id' => '551',
                      'delete' => '',
                      'selection_price_value' => '10',
                      'selection_price_type' => 0,
                      'selection_qty' => 1,
                      'selection_can_change_qty' => 0,
                      'position' => 0,
                      'is_default' => 1
                  )
              )
          );
          //flags for saving custom options/selections
          $bundleProduct->setCanSaveCustomOptions(true);
          $bundleProduct->setCanSaveBundleSelections(true);
          $bundleProduct->setAffectBundleProductSelections(true);
       
          //registering a product because of Mage_Bundle_Model_Selection::_beforeSave
          Mage::register('product', $bundleProduct);
       
          //setting the bundle options and selection data
          $bundleProduct->setBundleOptionsData($bundleOptions);
          $bundleProduct->setBundleSelectionsData($bundleSelections);
       
          $bundleProduct->save();
          echo 'success';
      } catch (Exception $e) {
          Mage::log($e->getMessage());
          echo $e->getMessage();
      }
      

      你可以在每行代码找到注释。我尽可能多地注释,这样有利于你们去理解。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 01 Oct 2015 09:31:48 +0000
      <![CDATA[实现Magento中的rel备用链接]]> https://www.360magento.com/blog/magento-rel-links/ 随着电子商务的发展,商品销往全球比以前容易多了。互联网没有界限,任何人都可以在舒适的家里访问你的商店。对于多店铺的需求也是日益明显。也许你希望让你的客户访问你的网站时看到的是自己的语言。

      当你设置你的多店铺时,Google有些指导和建议。这样能让你的网站索引更正确,排名更高。其中一条建议就是:如果你有翻译成其它语言的页面,使用rel="alternate"的链接。

      我们使用的语法看起来就像这样:

      <link rel="alternate" hreflang="es" href="http://es.example.com/" />
      

      如果把这个语法应用到Magento里,那看起来就像这样:

      
      
      

      现在我们就有了思路。让我们以注册我们的模块开始。

      app/etc/modules/Alwayly_Alternate.xml

      
      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Alternate>
                  <active>true</active>
                  <codePool>local</codePool>
              </Alwayly_Alternate>
         </modules>
      </config>
      

      让我们谈下模块的设置。我们需要做的就是把alternate链接放到每个页面的头部。一种方法就是在head.phtm文件里创建逻辑请求。更好的方式是,使用观测者监听一些时间,然后使用Magento中已经存在的addLinkRel()方法加入到head里。

      在这个例子里,我们将使用controller_action_layout_generate_blocks_after事件。也许这儿还有些更合适的事件,但这一次就用它了。

      app/code/local/Alwayly/Alternate/etc/config.xml

      
      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Alternate>
                  <version>1.0.0</version>
              </Alwayly_Alternate>
          </modules>
          <global>
              <helpers>
                  <alwayly_alternate>
                      <class>Alwayly_Alternate_Helper<class>
                  </alwayly_alternate>
              </helpers>
          </global>
          <frontend>
              <events>
                  <controller_action_layout_generate_blocks_after>
                      <observers>
                          <alwayly_alternate>
                              <type>singleton</type>
                              <class>Alwayly_Alternate_Model_Observer</class>
                              <method>alternateLinks</method>
                          </alwayly_alternate>
                      </observers>
                  </controller_action_layout_generate_blocks_after>
              </events>
          </frontend>
      </config>
      

      我们只是定义了观测者的名字和方法,现在来创建它。

      app/code/local/Alwayly/Alternate/Model/Observer.php

      
      class Alwayly_Alternate_Model_Observer
      {
       public function alternateLinks()
       {
         $headBlock = Mage::app()->getLayout()->getBlock('head');
       
         $stores = Mage::app()->getStores();
         $prod = Mage::registry('current_product');
         $categ = Mage::registry('current_category');
       
         if($headblock)
         {
           foreach ($stores as $store)
           {
             if($prod){
               $categ ? $categId=$categ->getId() : $categId = null;
               $url = $store->getBaseUrl() . Mage::helper('alwayly_alternate')->rewrittenProductUrl($prod->getId(), $categId, $store->getId());
             }else{
               $store->getCurrentUrl();
             }
             $storeCode = substr(Mage::getStoreConfig('general/locale/code', $store->getId()),0,2);
             $headBlock->addLinkRel('alternate"' . ' hreflang="' . $storeCode, $url);
           }
         }
         return $this;
       }
      }
      

      如你所见,我们循环所有的商店。当一个产品被设置,我们检查它的URL是否被重写。这是我们的助手要做的。如果一个产品没被设置,用getCurrentUrl()方法,我们能获取不同商店中的当前URL。

      例如我们现在的URL是 www.example.com/shirts.html,在德语版的商店,它会是www.example.com/shirts.html?___store=german或者是www.example.com/de/shirts.html,这取决于你的Magento设置。

      下一步,我们将获取区域代码的前一到两个字母。如果你有两个英文商店,一个为英国,一个为美国,那就完美了。在得到我们所要的信息后,我们将调用head块,使用addLinRel()方法将链接加到head。

      现在,创建你的助手。

      
      <?php
      class Alwayly_Alternate_Helper_Data extends Mage_Core_Helper_Abstract
      {
          public function rewrittenProductUrl($productId, $categoryId, $storeId)
          {
              $coreUrl = Mage::getModel('core/url_rewrite');
              $idPath = sprintf('product/%d', $productId);
              if ($categoryId) {
                  $idPath = sprintf('%s/%d', $idPath, $categoryId);
              }
              $coreUrl->setStoreId($storeId);
              $coreUrl->loadByIdPath($idPath);
              return $coreUrl->getRequestPath();
          }
      }
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 01 Oct 2015 09:23:50 +0000
      <![CDATA[在Magento网格列表中展示产品缩略图]]> https://www.360magento.com/blog/grids-show-thumbnail/ 编辑产品和改变产品在类别中的位置是一项不小的任务。特别是有一大堆产品需要编辑和排列,而且其中有些又很相似。

      当然,你可以通过SKU,ID,价格或者其它的一些东西来区别它们。但是都不会比在网格列表中展示缩略图好。

      在产品网格列表里展示缩略图并不复杂。有几种方法可以实现这个功能,但是几乎所有的方法都用到了渲染器去展示产品图片,就和我们即将做的一样。

      在这个例子中,我们将注册我们的模块,重写一个Magento后太网格的块——特别是“Manage Categories”,还要添加我们的代码来显示缩略图这个附加列。

      让我们开始吧!

      首先,注册我们的模块

      app/etc/modules/Alwayly_Thumbnail.xml

      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Thumbnail>
                  <active>true</active>
                  <codePool>local</codePool>
              </Alwayly_Thumbnail>
          </modules>
      </config>
      

      现在,配置你的模块,用你自己的版本来重写 ‘catalog_category_tab_product‘ 块。

      app/code/local/Alwayly/Thumbnail/etc/config.xml

      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Thumbnail>
                  <version>1.0.0</version>
              </Alwayly_Thumbnail>
          </modules>
          <global>
              <blocks>
                  <adminhtml>
                      <rewrite>                    <catalog_category_tab_product>Alwayly_Thumbnail_Block_Adminhtml_Catalog_Category_Tab_Product</catalog_category_tab_product>
                      </rewrite>
                  </adminhtml>
              </blocks>
          </global>
      </config>
      

      app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tab/Product.php中的代码粘贴到app/code/local/Alwayly/Thumbnail/Block/Adminhtml/Catalog/Category/Tab/Product.php

      <?php
      class Alwayly_Thumbnail_Block_Adminhtml_Catalog_Category_Tab_Product extends Mage_Adminhtml_Block_Widget_Grid
      {
          public function __construct()
          {
              parent::__construct();
              $this->setId('catalog_category_products');
              $this->setDefaultSort('entity_id');
              $this->setUseAjax(true);
          }
       
          public function getCategory()
          {
              return Mage::registry('category');
          }
       
          protected function _addColumnFilterToCollection($column)
          {
              // Set custom filter for in category flag
              if ($column->getId() == 'in_category') {
                  $productIds = $this->_getSelectedProducts();
                  if (empty($productIds)) {
                      $productIds = 0;
                  }
                  if ($column->getFilter()->getValue()) {
                      $this->getCollection()->addFieldToFilter('entity_id', array('in'=>$productIds));
                  }
                  elseif(!empty($productIds)) {
                      $this->getCollection()->addFieldToFilter('entity_id', array('nin'=>$productIds));
                  }
              }
              else {
                  parent::_addColumnFilterToCollection($column);
              }
              return $this;
          }
       
          protected function _prepareCollection()
          {
              if ($this->getCategory()->getId()) {
                  $this->setDefaultFilter(array('in_category'=>1));
              }
              $collection = Mage::getModel('catalog/product')->getCollection()
                                ->addAttributeToSelect('name')
                                ->addAttributeToSelect('sku')
                                ->addAttributeToSelect('price')
                                ->addAttributeToSelect('thumbnail')
                                ->addStoreFilter($this->getRequest()->getParam('store'))
                                ->joinField('position',
                                            'catalog/category_product',
                                            'position',
                                            'product_id=entity_id',
                                            'category_id='.(int) $this->getRequest()->getParam('id', 0),
                                            'left');
              $this->setCollection($collection);
       
              if ($this->getCategory()->getProductsReadonly()) {
                  $productIds = $this->_getSelectedProducts();
                  if (empty($productIds)) {
                      $productIds = 0;
                  }
                  $this->getCollection()->addFieldToFilter('entity_id', array('in'=>$productIds));
              }
       
              return parent::_prepareCollection();
          }
       
          protected function _prepareColumns()
          {
              if (!$this->getCategory()->getProductsReadonly()) {
                  $this->addColumn('in_category', array(
                      'header_css_class' => 'a-center',
                      'type'      => 'checkbox',
                      'name'      => 'in_category',
                      'values'    => $this->_getSelectedProducts(),
                      'align'     => 'center',
                      'index'     => 'entity_id'
                  ));
              }
              $this->addColumn('entity_id', array(
                  'header'    => Mage::helper('catalog')->__('ID'),
                  'sortable'  => true,
                  'width'     => '60',
                  'index'     => 'entity_id'
              ));
              $this->addColumn('name', array(
                  'header'    => Mage::helper('catalog')->__('Name'),
                  'index'     => 'name'
              ));
              $this->addColumn('image', array(
                  'header' => Mage::helper('catalog')->__('Image'),
                  'align' => 'left',
                  'index' => 'image',
                  'width'     => '97',
                  'renderer' => 'Alwayly_Thumbnail_Block_Adminhtml_Template_Grid_Renderer_Image'
              ));
              $this->addColumn('sku', array(
                  'header'    => Mage::helper('catalog')->__('SKU'),
                  'width'     => '80',
                  'index'     => 'sku'
              ));
              $this->addColumn('price', array(
                  'header'    => Mage::helper('catalog')->__('Price'),
                  'type'  => 'currency',
                  'width'     => '1',
                  'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE),
                  'index'     => 'price'
              ));
              $this->addColumn('position', array(
                  'header'    => Mage::helper('catalog')->__('Position'),
                  'width'     => '1',
                  'type'      => 'number',
                  'index'     => 'position',
                  'editable'  => !$this->getCategory()->getProductsReadonly()
                  //'renderer'  => 'adminhtml/widget_grid_column_renderer_input'
              ));
       
              return parent::_prepareColumns();
          }
       
          public function getGridUrl()
          {
              return $this->getUrl('*/*/grid', array('_current'=>true));
          }
       
          protected function _getSelectedProducts()
          {
              $products = $this->getRequest()->getPost('selected_products');
              if (is_null($products)) {
                  $products = $this->getCategory()->getProductsPosition();
                  return array_keys($products);
              }
              return $products;
          }
      }
      

      现在,插入上面的代码,这将选择一个产品的附加属性——“thumbnail”,创建一个名为“Image”的列。注意到,你可以在任何包含产品的网格里做这些,只需要重写一个不同的块。

      最后,我们将创建一个在89行被调用的自己的渲染器。

      
      'renderer' => 'Alwayly_Thumbnail_Block_Adminhtml_Template_Grid_Renderer_Image'
      
      app/code/local/Alwayly/Thumbnail/Block/Adminhtml/Template/Grid/Renderer/Image.php
      <?php
      class Alwayly_Thumbnail_Block_Adminhtml_Template_Grid_Renderer_Image extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
      {
          public function render(Varien_Object $row)
          {
              $val = Mage::helper('catalog/image')->init($row, 'thumbnail')->resize(97);
              $out = "<img src=". $val ." width='97px'/>";
              return $out;
          }
      }
      

      这个渲染器获取了一行对象作为一个参数。它调用的图像助手初始化缩略图大小并重新调整为97像素(你可以改成你需要或喜欢的大小)。之后,它返回出现在你网格里的图像标签。我们还需要考虑到产品没有图片的情况。

      最快捷的方式是复制产品占位符(placeholder)图像。我将Magento默认的占位符图像(skin\adminhtml\default\default\images\placeholder\thumbnail.jpg)拷贝到skin\adminhtml\default\default\images\catalog\product\placeholder\thumbnail.jpg

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 30 Sep 2015 08:07:26 +0000
      <![CDATA[用编程的方式创建一个可配置产品]]> https://www.360magento.com/blog/programmatically-magento-configurable/ 之前写过一篇关于在Magento中用编程创建简单产品的文章。那么,对于可配置产品来说,事情就变得复杂了点。

      如你所知,可配置产品就是由配置了不同选项(属性)的简单产品组成的。我们可以用这个结论来扩展我们创建简单产品的代码来进行配置。

      Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
      $simpleProduct = Mage::getModel('catalog/product');
      try {
      $simpleProduct
      //    ->setStoreId(1) //you can set data in store scope
          ->setWebsiteIds(array(1)) //website ID the product is assigned to, as an array
          ->setAttributeSetId(20) //ID of a attribute set named 'default'
          ->setTypeId('simple') //product type
          ->setCreatedAt(strtotime('now')) //product creation time
      //    ->setUpdatedAt(strtotime('now')) //product update time
          ->setSku('simple99y') //SKU
          ->setName('test simple product99') //product name
          ->setWeight(4.0000)
          ->setStatus(1) //product status (1 - enabled, 2 - disabled)
          ->setTaxClassId(4) //tax class (0 - none, 1 - default, 2 - taxable, 4 - shipping)
          ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) //catalog and search visibility
          ->setManufacturer(28) //manufacturer id
          ->setColor(24)
          ->setNewsFromDate('06/26/2014') //product set as new from
          ->setNewsToDate('06/30/2014') //product set as new to
          ->setCountryOfManufacture('AF') //country of manufacture (2-letter country code)
          ->setPrice(11.22) //price in form 11.22
          ->setCost(22.33) //price in form 11.22
          ->setSpecialPrice(00.44) //special price in form 11.22
          ->setSpecialFromDate('06/1/2014') //special price from (MM-DD-YYYY)
          ->setSpecialToDate('06/30/2014') //special price to (MM-DD-YYYY)
          ->setMsrpEnabled(1) //enable MAP
          ->setMsrpDisplayActualPriceType(1) //display actual price (1 - on gesture, 2 - in cart, 3 - before order confirmation, 4 - use config)
          ->setMsrp(99.99) //Manufacturer's Suggested Retail Price
          ->setMetaTitle('test meta title 2')
          ->setMetaKeyword('test meta keyword 2')
          ->setMetaDescription('test meta description 2')
          ->setDescription('This is a long description')
          ->setShortDescription('This is a short description')
          ->setMediaGallery(array('images' => array(), 'values' => array())) //media gallery initialization
          ->setStockData(array(
                  'use_config_manage_stock' => 0, //'Use config settings' checkbox
                  'manage_stock' => 1, //manage stock
                  'min_sale_qty' => 1, //Minimum Qty Allowed in Shopping Cart
                  'max_sale_qty' => 2, //Maximum Qty Allowed in Shopping Cart
                  'is_in_stock' => 1, //Stock Availability
                  'qty' => 999 //qty
              )
          )
          ->setCategoryIds(array(3, 10)); //assign product to categories
          $simpleProduct->save();
      } catch (Exception $e) {
          Mage::log($e->getMessage());
          echo $e->getMessage();
      }
      

      上面的代码将创建一个简单产品,这里我就不详细讲了。如果你想要深入了解,你可以点击这个链接看看我之前的那篇文章。

      现在我们要做的就是创建一个可配置产品并把这个简单产品指向它。

      $configProduct = Mage::getModel('catalog/product');,
      try {
      $configProduct
      //    ->setStoreId(1) //you can set data in store scope
              ->setWebsiteIds(array(1)) //website ID the product is assigned to, as an array
              ->setAttributeSetId(20) //ID of a attribute set named 'default'
              ->setTypeId('configurable') //product type
              ->setCreatedAt(strtotime('now')) //product creation time
      //    ->setUpdatedAt(strtotime('now')) //product update time
              ->setSku('configurable96') //SKU
              ->setName('test config product96') //product name
              ->setWeight(4.0000)
              ->setStatus(1) //product status (1 - enabled, 2 - disabled)
              ->setTaxClassId(4) //tax class (0 - none, 1 - default, 2 - taxable, 4 - shipping)
              ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) //catalog and search visibility
              ->setManufacturer(28) //manufacturer id
              ->setNewsFromDate('06/26/2014') //product set as new from
              ->setNewsToDate('06/30/2014') //product set as new to
              ->setCountryOfManufacture('AF') //country of manufacture (2-letter country code)
              ->setPrice(11.22) //price in form 11.22
              ->setCost(22.33) //price in form 11.22
              ->setSpecialPrice(00.44) //special price in form 11.22
              ->setSpecialFromDate('06/1/2014') //special price from (MM-DD-YYYY)
              ->setSpecialToDate('06/30/2014') //special price to (MM-DD-YYYY)
              ->setMsrpEnabled(1) //enable MAP
              ->setMsrpDisplayActualPriceType(1) //display actual price (1 - on gesture, 2 - in cart, 3 - before order confirmation, 4 - use config)
              ->setMsrp(99.99) //Manufacturer's Suggested Retail Price
              ->setMetaTitle('test meta title 2')
              ->setMetaKeyword('test meta keyword 2')
              ->setMetaDescription('test meta description 2')
              ->setDescription('This is a long description')
              ->setShortDescription('This is a short description')
              ->setMediaGallery(array('images' => array(), 'values' => array())) //media gallery initialization
              ->setStockData(array(
                      'use_config_manage_stock' => 0, //'Use config settings' checkbox
                      'manage_stock' => 1, //manage stock
                      'is_in_stock' => 1, //Stock Availability
                  )
              )
              ->setCategoryIds(array(3, 10)) //assign product to categories
          ;
          /**/
          /** assigning associated product to configurable */
          /**/
          $configProduct->getTypeInstance()->setUsedProductAttributeIds(array(92)); //attribute ID of attribute 'color' in my store
          $configurableAttributesData = $configProduct->getTypeInstance()->getConfigurableAttributesAsArray();
       
          $configProduct->setCanSaveConfigurableAttributes(true);
          $configProduct->setConfigurableAttributesData($configurableAttributesData);
       
          $configurableProductsData = array();
          $configurableProductsData['920'] = array( //['920'] = id of a simple product associated with this configurable
              '0' => array(
                  'label' => 'Green', //attribute label
                  'attribute_id' => '92', //attribute ID of attribute 'color' in my store
                  'value_index' => '24', //value of 'Green' index of the attribute 'color'
                  'is_percent' => '0', //fixed/percent price for this option
                  'pricing_value' => '21' //value for the pricing
              )
          );
          $configProduct->setConfigurableProductsData($configurableProductsData);
          $configProduct->save();
       
          echo 'success';
      } catch (Exception $e) {
          Mage::log($e->getMessage());
          echo $e->getMessage();
      }
      

      就是这样了!你的可配置产品被合理设置并在前台可见。值得注意的是,你需要分配同样的属性集到可配置产品和它相关的产品。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 30 Sep 2015 07:33:53 +0000
      <![CDATA[以编程方式(手动)创建Magento中的简单产品]]> https://www.360magento.com/blog/programmatically-magento-simple/ 在开发过程中,你经常需要一些可用的数据来做测试。Magento提供了包含一些产品的示例数据。可事实是,当你创建了自己的属性集或者产品类型,想要加入到你的产品里去时,这个示例数据就显得没什么用了。针对这点,你需要自己添加一些商品。

      有时在后台添加就可以了,但当你要添加多种产品、继续开发新特征或者做一些大的改动时,用后台操作就变得很痛苦了。这个问题用编程方式来添加产品就能轻松解决了。我将用这种方法来添加一个简单产品。你可以修改一下这个代码来适应其它产品类型,也可以用它来作为产品导入脚本。

      你可以通过一个observer来调用,设置为一个控制器方法,或者从一个视图文件中调用,随你喜欢。要注意的是,当你观测一些事件时不要使用调用每个控制器方法的那个。如果你使用了,那么确定产品中是否存在同样的SKU。针对这种情况,你可以用下面代码中第四行的“if”判断。

      如果你没有按照我说的做,那么会出现下面的SQL报错:

      SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '193-1' for key 'UNQ_CATALOGINVENTORY_STOCK_ITEM_PRODUCT_ID_STOCK_ID'
      

      下面就是我提到的代码:

      <?php
      Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
      $product = Mage::getModel('catalog/product');
      //    if(!$product->getIdBySku('testsku61')):
       
      try{
      $product
      //    ->setStoreId(1) //you can set data in store scope
          ->setWebsiteIds(array(1)) //website ID the product is assigned to, as an array
          ->setAttributeSetId(9) //ID of a attribute set named 'default'
          ->setTypeId('simple') //product type
          ->setCreatedAt(strtotime('now')) //product creation time
      //    ->setUpdatedAt(strtotime('now')) //product update time
       
          ->setSku('testsku61') //SKU
          ->setName('test product21') //product name
          ->setWeight(4.0000)
          ->setStatus(1) //product status (1 - enabled, 2 - disabled)
          ->setTaxClassId(4) //tax class (0 - none, 1 - default, 2 - taxable, 4 - shipping)
          ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) //catalog and search visibility
          ->setManufacturer(28) //manufacturer id
          ->setColor(24)
          ->setNewsFromDate('06/26/2014') //product set as new from
          ->setNewsToDate('06/30/2014') //product set as new to
          ->setCountryOfManufacture('AF') //country of manufacture (2-letter country code)
       
          ->setPrice(11.22) //price in form 11.22
          ->setCost(22.33) //price in form 11.22
          ->setSpecialPrice(00.44) //special price in form 11.22
          ->setSpecialFromDate('06/1/2014') //special price from (MM-DD-YYYY)
          ->setSpecialToDate('06/30/2014') //special price to (MM-DD-YYYY)
          ->setMsrpEnabled(1) //enable MAP
          ->setMsrpDisplayActualPriceType(1) //display actual price (1 - on gesture, 2 - in cart, 3 - before order confirmation, 4 - use config)
          ->setMsrp(99.99) //Manufacturer's Suggested Retail Price
       
          ->setMetaTitle('test meta title 2')
          ->setMetaKeyword('test meta keyword 2')
          ->setMetaDescription('test meta description 2')
       
          ->setDescription('This is a long description')
          ->setShortDescription('This is a short description')
       
          ->setMediaGallery (array('images'=>array (), 'values'=>array ())) //media gallery initialization
          ->addImageToMediaGallery('media/catalog/product/1/0/10243-1.png', array('image','thumbnail','small_image'), false, false) //assigning image, thumb and small image to media gallery
       
          ->setStockData(array(
                             'use_config_manage_stock' => 0, //'Use config settings' checkbox
                             'manage_stock'=>1, //manage stock
                             'min_sale_qty'=>1, //Minimum Qty Allowed in Shopping Cart
                             'max_sale_qty'=>2, //Maximum Qty Allowed in Shopping Cart
                             'is_in_stock' => 1, //Stock Availability
                             'qty' => 999 //qty
                         )
          )
       
          ->setCategoryIds(array(3, 10)); //assign product to categories
      $product->save();
      //endif;
      }catch(Exception $e){
      Mage::log($e->getMessage());
      }

      我们设定这款产品在“默认值”范围。您可以为一个特定的商店取消第5行的代码来设置产品数据,。例如,你可以这样做:

      ...
          ->setMetaTitle('test meta title 2')
          ->setMetaKeyword('test meta keyword 2')
          ->setMetaDescription('test meta description 2')
          ->setStoreId(2)
          ->setMetaTitle('Some other meta title')
          ->setMetaKeyword('Some other meta keyword')
          ->setMetaDescription('Some other meta description')
      $product->save();
      

      上面的代码将为ID为2的商店设置不同的meta name。

      你可以通过登录到产品存储传输数据来找到所有你能设置的产品值。我在考虑当你存储商品是后台调用的ProductController里的saveAction方法。 app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php

      public function saveAction()
      {
          $storeId        = $this->getRequest()->getParam('store');
          $redirectBack   = $this->getRequest()->getParam('back', false);
          $productId      = $this->getRequest()->getParam('id');
          $isEdit         = (int)($this->getRequest()->getParam('id') != null);
       
          $data = $this->getRequest()->getPost();
          if ($data) {
              Mage::log($data);

      只需要把最后一行代码加入到相应的位置。当你完成开发以后记得删除。这将获取一个你存储的数据的数组。例如,为了设置 [meta_title],你会使用setMetaTitle(‘somevalue’)魔术方法。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 29 Sep 2015 03:16:35 +0000
      <![CDATA[获取magento可配置产品里被选中的简单产品]]> https://www.360magento.com/blog/simple-id-in-configurable/ 如果你想在Magento客户端获取可配置产品里被选中的简单产品,你有很多种不同的方法。

      这里有一种简单的方法,不用代码修改,不要新的模版甚至模。值需要一个Java脚本和布局更新。

      
      Product.Config.prototype.getIdOfSelectedProduct = function()
      {
           var existingProducts = new Object();
       
           for(var i=this.settings.length-1;i>=0;i--)
           {
               var selected = this.settings[i].options[this.settings[i].selectedIndex];
               if(selected.config)
               {
               	for(var iproducts=0;iproducts<selected.config.products.length;iproducts++)
               	{
               		var usedAsKey = selected.config.products[iproducts]+"";
               		if(existingProducts[usedAsKey]==undefined)
               		{
               			existingProducts[usedAsKey]=1;
               		}
               		else
               		{
               			existingProducts[usedAsKey]=existingProducts[usedAsKey]+1;
               		}
                   }
               }
           }
       
           for (var keyValue in existingProducts)
           {
           	for ( var keyValueInner in existingProducts)
               {
               	if(Number(existingProducts[keyValueInner])<Number(existingProducts[keyValue]))
               	{
               		delete existingProducts[keyValueInner];
               	}
               }
           }
       
           var sizeOfExistingProducts=0;
           var currentSimpleProductId = "";
           for ( var keyValue in existingProducts)
           {
           	currentSimpleProductId = keyValue;
           	sizeOfExistingProducts=sizeOfExistingProducts+1
           }
       
           if(sizeOfExistingProducts==1)
           {
          	 alert("Selected product is: "+currentSimpleProductId)
           }
      }
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 29 Sep 2015 01:38:21 +0000
      <![CDATA[中国2015上半年跨境电商交易额达7.64万亿 ]]> https://www.360magento.com/blog/news-ecommerce-china/ 交易规模:2015上半年中国跨境电商交易规模达2万亿

      2015年上半年,中国跨境电商交易规模为2万亿,同比增长42.8%,占我国进出口总值的17.3%。

      从上述数据分析可以知道,上半年中国对外贸易呈现低迷态势,而跨境电子商务则呈现出蓬勃的发展态势。未来会有更多企业加入跨境电子商务行列,中国跨境电子商务从规模到质量都会有大幅度的提高,在国际市场的影响力会进一步增强。

      随着跨境电商试点城市数量的增多,电商平台跨境业务将借机不断扩大,地方政府也将加速建设自有电商服务平台,由此产生的大量跨境贸易交易规模将在未来予以呈现。

      进出口比例:出口84.8% 进口比例15.2%

      2015年上半年,中国跨境电商的进出口结构出口占比达到84.8%,进口比例15.2%。

      “目前,中国出口电商仍为跨境电商的主角,随着政策的推动以及消费需求的旺盛,进口电商得到了快速的发展,占比比例有所上升,但幅度不大。试点政策的逐步放开以及更多企业的参与,都将推动进口电商的发展。”中国电子商务研究中心高级分析师张周平表示。

      模式结构:跨境电商B2B占比91.9% B2C占比8.1%

      2015年上半年,中国跨境电商的交易模式跨境电商B2B交易占比达到91.9%,跨境电商B2B交易占据绝对优势,跨境电商B2C交易占比8.1%。

      对此,中国电子商务研究中心高级分析师张周平认为,B2B模式的交易方式始终占据行业主流,这跟两种模式针对的对象有关。B2B交易量级大、且订单稳定, 所以该种方式在未来仍是主流。B2C模式下订单趋向碎片化和小额化,但需求强劲,在未来几年,B2C占比比例也将会逐步提升。

      市场趋势

        趋势一:跨境电商成为对外贸易“新增长点”

      2015年是中国跨境电商的转折年。激烈的价格战和同质化竞争,传统跨境电商的经营模式和增长模式受到严峻考验。以草根创业和价格战为特色的第一波跨境电 商已经过去,未来一段时期将迎来第二波跨境电商热潮。传统企业和品牌商的觉醒和爆发,中小制造型企业面对买家需求封闭、订单周期长、汇率风险高、利润空间 低等传统外贸限制,对跨境电子商务的需求更为迫切。出口易在原来的基础上更要抓住机遇发展自身,满足市场对新型跨境电商的需求。

      趋势二:产品品类和销售市场更加多元化

      随着跨境电商的发展,跨境电商交易呈现新的特征:交易产品向多品类延伸、交易对象向多区域拓展。从销售产品品类看,跨境电商企业销售的产品品类从服装服饰、3C电子、计算机及配件、家居园艺、珠宝、汽车配件、食品药品等便捷运输产品向家居、汽车等大型产品扩展。

      趋势三:跨境进口电商将集中爆发

      未来跨境进口电商将集中爆发,随着政策倾斜进入快速“成长期”。2014年,在“跨境交易”与“电子商务”双引擎的拉动下,跨境进口型电商风生水起。先是 天猫、亚马逊中国,继而是苏宁、聚美优品纷纷挤进跨境电商2.0时代,进入产业信息化时代,即结合传统资源,打造海外供应链,多渠道运营(自营或招商的形 式),拉开了品牌国际化战略的序幕。

      趋势四:品牌争夺战打响,成关键转折点

      各大电商平台开始盯上有限的品牌资源,中小电商也在激烈的价格战中意识到品牌的重要性。但品牌建立需要一定的历史背景,市场条件等多种因素,中国跨境电商 创牌之路将会异常艰辛,但机会尚存,如在新兴市场国家创牌就相对较易,比如M2C供销平台的品质供销品牌聚焦,为各大电商卖家提供了更多机会。在技术日新 月异的电子产品、智能产品方面,中国和发达国家之间其实处于同一起跑线,更加容易创牌成功,中国跨境电商的发展其实已经到了一个非常关键的转折点。(来 源:中国电子商务研究中心

      360Magento为中国大中小企业的跨境电商提供有力的技术支持后盾,为中国创建跨境电商独立品牌做出重要贡献,请联系我们,竭诚为您服务,祝君生意红红火火

      ]]>
      Mon, 28 Sep 2015 14:15:13 +0000
      <![CDATA[Magento中上一个/下一个产品按钮]]> https://www.360magento.com/blog/magento-prevnext-extension/ 现在,已经有好几个Magento的上一个/下一个插件。说实话,我并不知道它们功能如何,因为我没用过。我打算自己写这个功能,依靠分层导航筛选并按网格列表中的顺序排列。这儿是插件代码的示例(部分但是功能齐全)

      首先我们创建Alwayly_Prevnext插件的config.xml

      ...
          <frontend>         
              <events>
                  <controller_action_postdispatch>
                      <observers>
                          <alwayly_prevnext_set_filtered_category_product_collection>
                              <class>alwayly_prevnext/observer</class>
                              <method>setAlwaylyFilteredCategoryProductCollection</method>
                          </alwayly_prevnext_set_filtered_category_product_collection>
                      </observers>                
                  </controller_action_postdispatch>
              </events>   
          </frontend>
      ...
      
      

      现在,我们实现观测方法。在这里,我抓取已经读取的产品集合,产品网格网格列表的最后一个产品。如你所见,我注重 “category” 控制器, “view”动作,从集合中提取产品ID并将它们设置到alwayly_filtered_category_product_collection的session关键字下。这样一来我就能获取最后被详细页最后被浏览的产品,然后确定它的前一个和后一个产品。

      class Alwayly_Prevnext_Model_Observer
      {
          public function setAlwaylyFilteredCategoryProductCollection()
          {
              /**
               * There might be some illogical buggy behavior when coming directly 
               * from "Related products" / "Recently viewed" products block. 
               * Nothing that should break the page however.
               */
      	if (Mage::app()->getRequest()->getControllerName() == 'category' && Mage::app()->getRequest()->getActionName() == 'view') {
       
      		$products = Mage::app()->getLayout()
      				->getBlockSingleton('Mage_Catalog_Block_Product_List')
      				->getLoadedProductCollection()
      				->getColumnValues('entity_id');
       
      		Mage::getSingleton('core/session')
      				->setAlwaylyFilteredCategoryProductCollection($products);
       
      		unset($products);
      	}
       
      	return $this;        
          }
      } 
      

      最后,助手类支持getPreviousProduct和getNextProduct方法

      class Alwayly_Prevnext_Helper_Data extends Mage_Core_Helper_Abstract
      {
          /**
           * @return Mage_Catalog_Model_Product or FALSE
           */
          public function getPreviousProduct()
          {
                  $prodId = Mage::registry('current_product')->getId();
       
                  $positions = Mage::getSingleton('core/session')->getAlwaylyFilteredCategoryProductCollection();
       
                  if (!$positions) {
                      $positions = array_reverse(array_keys(Mage::registry('current_category')->getProductsPosition()));
                  }
       
                  $cpk = @array_search($prodId, $positions);
       
                  $slice = array_reverse(array_slice($positions, 0, $cpk));
       
                  foreach ($slice as $productId) {
                          $product = Mage::getModel('catalog/product')
                                                          ->load($productId);
       
                          if ($product && $product->getId() && $product->isVisibleInCatalog() && $product->isVisibleInSiteVisibility()) {
                                  return $product;
                          }
                  }
       
                  return false;
          }
       
          /**
           * @return Mage_Catalog_Model_Product or FALSE
           */
          public function getNextProduct()
          {
                  $prodId = Mage::registry('current_product')->getId();
       
                  $positions = Mage::getSingleton('core/session')->getAlwaylyFilteredCategoryProductCollection();
       
                  if (!$positions) {
                      $positions = array_reverse(array_keys(Mage::registry('current_category')->getProductsPosition()));
                  }            
       
                  $cpk = @array_search($prodId, $positions);
       
                  $slice = array_slice($positions, $cpk + 1, count($positions));
       
                  foreach ($slice as $productId) {
                          $product = Mage::getModel('catalog/product')
                                                          ->load($productId);
       
                          if ($product && $product->getId() && $product->isVisibleInCatalog() && $product->isVisibleInSiteVisibility()) {
                                  return $product;
                          }
                  }
       
                  return false;
          }
      }
      

      这个方法里有个问题,它不能弥补剩余类别产品中可能的页。事实是,抓去类别产品ID的时候我们仍然不知道其它可能页面中这个产品的ID。然而,这将要求在服务器上更多的负载,因为它需要一个或两个额外的数据库查询。此外,时不时地可能出现一些不合逻辑的上一个/下一个。因此,这个方法还有提升的空间。但要知道的是,这种方法并不会破坏什么。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 28 Sep 2015 11:00:20 +0000
      <![CDATA[15分钟内创建一个magento"Facebook like"按钮插件]]> https://www.360magento.com/blog/facebook-like-button-extension/ Facebook Like按钮很简单,也容易实现。你所要做的只是从Facebook开发者的网站粘贴2-3节,然后调整下。

      既然我们要给Magento编代码,那么何不做一个插件呢,Alwayly_Flike。考虑到工作的预算和时间,我要尽可能快地完成编码,但是任然要按照“Magento规则”。考虑到这一点,下面是我插件的config.xml内容:

      <config>
          <modules>
              <Alwayly_Flike>
                  <version>1.0.0.0</version>
              </Alwayly_Flike>
          </modules>
          <frontend>
              <layout>
                  <updates>
                      <alwayly_flike>
                          <file>alwayly/flike/flike.xml</file>
                      </alwayly_flike>
                  </updates>
              </layout>        
          </frontend>
      </config>
      

      由于上面的配置中包含了flike.xml,所以我们需要添加alwayly/flike/flike.xml到我能的主题布局文件夹下。这是flike.xml代码:

      <layout version="0.1.0">
         <catalog_product_view>
              <reference name="head">
                  <block type="core/template" name="alwayly_flike_tags" template="alwayly/flike/tags.phtml" before="-" />
              </reference>        
              <reference name="after_body_start">
                  <block type="core/template" name="alwayly_flike_js" template="alwayly/flike/js.phtml" before="-" />          
              </reference>
              <reference name="alert.urls">
                  <block type="core/template" name="alwayly_flike_button" template="alwayly/flike/button.phtml" before="-" />
              </reference>
          </catalog_product_view>
      </layout>
      

      为了简单起见和预算的限制,我决定用“core/template”模块。现在我们就要开始写flike.xml中提到的tags.phtml,js.phtml和button.phtml文件了。

      tags.phtml文件包含“开放图形标签”,当我们Like我们的产品时,我们要获取正确的产品图片描述等等。由于这些都需要在网页的“head”下,所以我引用了head模块。下面是tags.phtml的代码:

      <?php $_product = Mage::registry('current_product') ?>
      <?php if ($_product && $_product->getId()): ?>
      <meta property="og:title" content="<?php echo $this->stripTags($_product->getName(), null, true) ?>" />
      <meta property="og:type" content="product" />
      <meta property="og:image" content="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(130, 110); ?>" />
      <meta property="og:url" content="<?php echo $_product->getProductUrl() ?>" />
      <meta property="og:site_name" content="<?php echo Mage::app()->getStore()->getName() ?>" />
      <?php endif; ?>
      

      注意图片大小周围的细节。这符合Facebook官方对og的定义:图像作为Feed链接。缩略图的宽和高超过50像素,不超过130x110像素。高和宽的比或者宽和高的比不超过3.例如139x39像素的图片就不会显示,宽和高的比为3.23超过了3。图片会被重新定义成合适的大小。

      js.phtml文件包含Like按钮的JAVA脚本:

      <?php $_product = Mage::registry('current_product') ?>
      <?php if ($_product && $_product->getId()): ?>
      <div id="fb-root"></div>
      <script>
      (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s); js.id = id;
        js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
        fjs.parentNode.insertBefore(js, fjs);
      }(document, 'script', 'facebook-jssdk'));
      </script>
      <?php endif; ?>
      

      最后,button.phtml包含实际的按钮:

      <?php $_product = Mage::registry('current_product') ?>
      <?php if ($_product && $_product->getId()): ?>
      <div class="fb-like" data-href="<?php echo $_product->getProductUrl() ?>" data-send="true" data-width="450" data-show-faces="true"></div>
      <?php endif; ?>
      

      就是这样了。如果你没有在你的主题你做过多的修改,更确切地说删除产品详细页的“alert.urls” 块。那么你就能在产品名字附近看到Facebook Like按钮了。

      鉴于这是一个简单的例子,它还有很大的空间可供你开发。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 28 Sep 2015 08:47:33 +0000
      <![CDATA[管理Magento账户面板的导航链接]]> https://www.360magento.com/blog/managing-navigation-links/ 在本文中,我将演示如何管理用户账户面板里的导航链接:一种去掉账户面板链接时要避免的方式和另一种要执行的方式。

      一种删除指定链接的方法是注释掉显示这个链接的动作。我将以账户面板的 “Account Information”链接为例,这个链接位于 app/design/frontend/base/default/layout/customer.xml

      <action method="addLink" translate="label" module="customer">
        <name>account</name>
        <path>customer/account/</path>
        <label>Account Dashboard</label>
      </action>
      

      然而,编辑Magento的核心文件从来都不是一个好的想法。我们将用些不一样的东西来替代这个方法。

      首先,我们必须编辑我们的config.xml文件,我们要重写Magento的核心文件。

      
      <global>
          <blocks>
              <customer>
                  <rewrite>
                      <account_navigation>Alwayly_Core_Block_Customer_Account_Navigation</account_navigation>
                  </rewrite>
              </customer>
          </blocks>
      </global>
      

      接着,我们要定义我们的布局文件:

          <frontend>
              <layout>
                  <updates>
                      <alwayly_core>
                          <file>alwayly_core.xml</file>
                      </alwayly_core>
                  </updates>
              </layout>
          </frontend>
      

      下一步就是用下面的代码创建Block/Customer/Account/Navigation.php

      class Alwayly_Core_Block_Customer_Account_Navigation extends Mage_Customer_Block_Account_Navigation
      {
          public function removeLinkByName($name) {
              unset($this->_links[$name]);
          }
      }
      

      最后要做的就是创建布局文件app/design/frontend/default/default/layout/alwayly_core.xml

      
      <?xml version="1.0" ?>
      <layout version="0.1.0">
          <customer_account translate="label">
              <reference name="customer_account_navigation">
                  <action method="removeLinkByName"><name>billing_agreements</name></action>
                  <action method="removeLinkByName"><name>recurring_profiles</name></action>
                  <action method="removeLinkByName"><name>tags</name></action>
                  <action method="removeLinkByName"><name>my_wishlist</name></action>
                  <action method="removeLinkByName"><name>OAuth Customer Tokens</name></action>
                  <action method="removeLinkByName"><name>my_downloadable_products</name></action>
              </reference>
          </customer_account>
      </layout>
      

      现在,对于每个我们想要移除的导航链接,我们需要加上连接名并把链接名写入名字标签。

      下面列举出账户面板导航链接名(按默认显示排列)

      • Account Dashboard
      • Account Information
      • Address Book
      • My Orders
      • Billing Agreements
      • Recurring Profiles
      • My Product Reviews
      • My Wishlist
      • My Applications
      • Newsletter Subscriptions
      • My Downloadable Products

      添加一个新的导航链接相对来说简单一些。我们要做的只是将以下代码加到我们的布局文件中

      <?xml version="1.0" ?>
      <layout version="0.1.0">
         <customer_account translate="label">
              <reference name="customer_account_navigation">
                  <action method="addLink">
                      <name>test checkout</name>
                      <path>checkout</path>
                      <label>Alwayly Checkout</label>
                  </action>
              </reference>
          </customer_account>
      </layout>
      

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 28 Sep 2015 04:43:18 +0000
      <![CDATA[Magento中产品库存不报警解决方案]]> https://www.360magento.com/blog/product-stock-alerts/ 最近我们的一个客户联系我们,告诉我们产品报警功能不再工作。在调查后,我发现最后的一封产品报警邮件是几个月前的。在此期间,我们已经在网站升级到Magento的EE,起初我想,也许在升级过程中出了问题。另一种可能是,客户也许修改了Transactional Email Template。在看完日志文件后,我没发现任何相关的邮件。系统虽然没有发送其它电子邮件。

      在调查过程中,我看论坛上的其它开发者有相似的问题也没解决的。在追寻和查找后,我们发现问题所在。

      简单说来,这个事件在Magento处理产品报库存警的集合方法里。我们的客户有超过40000封订阅和超过30000个需要将“缺货”状态改为“有货”。所以当Magento尝试从product_alert_stock表读取40000条记录到集合里的时候,由于内存限制而失败了。可能你的product_alert_stock表有超过20000记录时,产品库存报警功能就失效了。

      解决方案相对简单。通过以1000为集合创建分页来遍历超过30000条记录。正如Magento在系统中所做的那样。新的功能是通过遍历所有的这些记录,循环出status=0(未处理)的记录,检查产品现在是否有货。当true=> set status=1就发送电子邮件通知客户。

      那么,让我们创建我们的模块,Alwayly_ProductAlert,这将提高Magento方法。

      1. Create file in app/etc/modules/ Alwayly_ProductAlert.xml with the following content:

      
      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_ProductAlert>
                  <active>true</active>
                  <codePool>local</codePool>
              </Alwayly_ProductAlert>
          </modules>
      </config>
      

      2. Create file in app/code/local/Alwayly/ProductAlert/etc/ config.xml with the following content:

      
      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_ProductAlert>
                  <version>1.0.0.0</version>
              </Alwayly_ProductAlert>
          </modules>
          <global>
              <models>
                  <productalert>
                      <rewrite>
                          <observer>Alwayly_ProductAlert_Model_Observer</observer>
                      </rewrite>
                  </productalert>
              </models>
          </global>
      </config>
      

      你可以看到我们重写了Mage_ProductAlert_Model_Observer类

      Create file in /www/app/code/local/Alwayly/ProductAlert/Model/ Observer.php with the following content:

      
      <?php
       
      /*
       * ProductAlert observer
      */
      class Alwayly_ProductAlert_Model_Observer extends Mage_ProductAlert_Model_Observer
      {
           /**
           * Process stock emails
           *
           * @param Mage_ProductAlert_Model_Email $email
           * @return Mage_ProductAlert_Model_Observer
           */
          protected function _processStock(Mage_ProductAlert_Model_Email $email)
          {
       
              $email->setType('stock');
       
              foreach ($this->_getWebsites() as $website) {
       
                  /* @var $website Mage_Core_Model_Website */
       
                  if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
       
                      continue;
                  }
                  if (!Mage::getStoreConfig(
                      self::XML_PATH_STOCK_ALLOW,
                      $website->getDefaultGroup()->getDefaultStore()->getId()
                  )) {
       
                      continue;
                  }
                  try {
       
                      $wholeCollection = Mage::getModel('productalert/stock')
                          ->getCollection()
      //                   ->addWebsiteFilter($website->getId())
                          ->addFieldToFilter('website_id', $website->getId())
                          ->addFieldToFilter('status', 0)
                      ;
      //                $wholeCollection->getSelect()->order('alert_stock_id DESC');
       
                      /*       table: !product_alert_stock!
                      alert_stock_id: 1
                         customer_id: 1
                          product_id: 1
                          website_id: 1
                            add_date: 2013-04-26 12:08:30
                           send_date: 2013-04-26 12:28:16
                          send_count: 2
                              status: 1
                      */
                  }
                  catch (Exception $e) {
                      Mage::log('error-1-collection $e=' . $e->getMessage(), false, 'product_alert_stock_error.log', true);
                      $this->_errors[] = $e->getMessage();
                      return $this;
                  }
       
                  $previousCustomer = null;
                  $email->setWebsite($website);
       
                  try {
       
                      $originalCollection = $wholeCollection;
                      $count = null;
                      $page  = 1;
                      $lPage = null;
                      $break = false;
       
                      while ($break !== true) {
                          $collection = clone $originalCollection;
                          $collection->setPageSize(1000);
                          $collection->setCurPage($page);
                          $collection->load();
                          if (is_null($count)) {
                              $count = $collection->getSize();
                              $lPage = $collection->getLastPageNumber();
                          }
                          if ($lPage == $page) {
                              $break = true;
                          }
       
                          Mage::log('page=' . $page, false, 'check_page_count.log', true);
                          Mage::log('collection=' . (string)$collection->getSelect(), false, 'check_page_count.log', true);
       
                          $page ++;
       
                          foreach ($collection as $alert) {
       
                              try {
       
                                  if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) {
       
                                      $customer = Mage::getModel('customer/customer')->load($alert->getCustomerId());
                                      if ($previousCustomer) {
                                          $email->send();
                                      }
                                      if (!$customer) {
                                          continue;
                                      }
                                      $previousCustomer = $customer;
                                      $email->clean();
                                      $email->setCustomer($customer);
       
                                  }
                                  else {
       
                                      $customer = $previousCustomer;
                                  }
       
                                  $product = Mage::getModel('catalog/product')
                                      ->setStoreId($website->getDefaultStore()->getId())
                                      ->load($alert->getProductId());
                                  /* @var $product Mage_Catalog_Model_Product */
                                  if (!$product) {
       
                                      continue;
                                  }
       
                                  $product->setCustomerGroupId($customer->getGroupId());
       
                                  if ($product->isSalable()) {
       
                                      $email->addStockProduct($product);
       
                                      $alert->setSendDate(Mage::getModel('core/date')->gmtDate());
                                      $alert->setSendCount($alert->getSendCount() + 1);
                                      $alert->setStatus(1);
                                      $alert->save();
       
                                  }
                              }
                              catch (Exception $e) {
                                  Mage::log('error-2-alert $e=' . $e->getMessage(), false, 'product_alert_stock_error.log', true);
                                  $this->_errors[] = $e->getMessage();
                              }
                          }
                      }
       
                      Mage::log("\n\n", false, 'check_page_count.log', true);
       
                  } catch (Exception $e) {
                      Mage::log('error-3-steps $e=' . $e->getMessage(), false, 'product_alert_stock_error.log', true);
                  }
       
                  if ($previousCustomer) {
                      try {
                          $email->send();
                      }
                      catch (Exception $e) {
                          $this->_errors[] = $e->getMessage();
                      }
                  }
              }
       
              return $this;
          }
       
          /**
           * Run process send product alerts
           */
          public function process()
          {
              Mage::log('ProductAlert started @' . now(), false, 'product_alert_workflow.log', true);
       
              $email = Mage::getModel('productalert/email');
              /* @var $email Mage_ProductAlert_Model_Email */
              $this->_processPrice($email);
              $this->_processStock($email);
              $this->_sendErrorEmail();
       
              Mage::log('ProductAlert finished @' . now(), false, 'product_alert_workflow.log', true);
       
              return $this;
          }
      }
      

      你可以看到,我们重写了process()和 _processStock()方法。在process()方法中,我们添加了Mage::log()创建起止时间到var/log/product_alert_workflow.log。这样我们就能知道脚本是否执行完成。同样的,我们增强_processStock()方法的功能,我们增加了一些Mage:log()调用来跟踪,看所有的行为是否按期待的方式表现。

      最后,如果你不想等待你的Cron被触发,你可以在Magento根目录下创建一个文件,让我们调用它。

      Alwayly_cron.php

      
      <?php
      
      require_once 'app/Mage.php';
      Mage::app();
       
      try {
          Mage::getModel('productalert/observer')-&gtprocess();
      } catch (Exception $e) {
          Mage::log('error-0-start $e=' . $e-&gtgetMessage() . ' @' . now(), false, 'product_alert_stock_error.log', true);
      }
      

      就是这些了,这个解决思路同样适用于产品价格报警。

      360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 27 Sep 2015 15:10:56 +0000
      <![CDATA[向magento顶部菜单添加链接]]> https://www.360magento.com/blog/adding-links-to-topmenu/ 向顶部菜单或者主菜单中添加东西听起来很简单。但是,我们这里谈论的是Magento,它并不像听起来的那么容易。一种特殊的方式创建菜单项(不使用后台categories)让这个听起来简单的任务成了一场噩梦。幸运的是,Magento中藏有这么一个方法。

      Magento的逻辑只允许类别(categories)出现在顶部导航。当创建一个类别的时候只要设置Include in Navigation Menu就会显示在导航里。Magento已经解释了通过创建一个假的类别和重定向一个特殊的页面来添加一个菜单项。但他们也给了个事件挂钩去对顶部菜单做更灵活的事情。

      Config

      首先,在config.xml中通过添加下面的代码来定义挂钩。通过这个我们简单地添加当一个时间,当挂钩、模型、方法名被请求时调度事件就会去掉它。

      
      <config>
          <frontend>
              <events>
                  <page_block_html_topmenu_gethtml_before>
                      <observers>
                          <my_module>
                              <class>my_module/observer</class>
                              <method>addToTopmenu</method>
                          </my_module>
                      </observers>
                  </page_block_html_topmenu_gethtml_before>
              </events>
         </frontend>
      </config>
      

      Observer

      现在,一个包含addTopmenu方法的观察者已经在config.xml中被定义。下面的代码只是个例子,添加一个名为 “Categories”的顶部菜单项以及子分类项,类别名。好了,这样我们就能创建嵌套菜单项。

      
      public function addToTopmenu(Varien_Event_Observer $observer)
      {
          $menu = $observer->getMenu();
          $tree = $menu->getTree();
       
          $node = new Varien_Data_Tree_Node(array(
                  'name'   => 'Categories',
                  'id'     => 'categories',
                  'url'    => Mage::getUrl(), // point somewhere
          ), 'id', $tree, $menu);
       
          $menu->addChild($node);
       
          // Children menu items
          $collection = Mage::getResourceModel('catalog/category_collection')
                  ->setStore(Mage::app()->getStore())
                  ->addIsActiveFilter()
                  ->addNameToResult()
                  ->setPageSize(3);
       
          foreach ($collection as $category) {
              $tree = $node->getTree();
              $data = array(
                  'name'   => $category->getName(),
                  'id'     => 'category-node-'.$category->getId(),
                  'url'    =>> $category->getUrl(),
              );
       
              $subNode = new Varien_Data_Tree_Node($data, 'id', $tree, $node);
              $node->addChild($subNode);
          }
      }
      

      360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 27 Sep 2015 13:46:34 +0000
      <![CDATA[Magento中如何给特定对象创建布局句柄]]> https://www.360magento.com/blog/layout-update-handles/ Magento中每个Http请求结果中都会有一些布局句柄,这些句柄可以用来定制所需页面的布局。如果你曾经尝试找出magento中的布局句柄,你会发现有很多。这些句柄基于不同的变量,不同的计算。

      根据用户是否登录,magento使用customer_logged_in和customer_logged_out句柄。不同的店铺也有不同的布局更新(例如STORE_default,STORE_cars,STORE_fashion ...)。主题有自己的布局句柄(例如THEME_frontend_default_default,THEME_frontend_enterprise_default)。

      当一个网站使用“Shop by Brand”插件的时候,客户问我们是否能改变一个brand页面的布局。为了实现这个功能,我们必须扩展这个插件,让每个brand页面有它自己的更新句柄。

      你可能注意到Magento使用这个功能创建唯一的布局句柄给不同的类别(如CATEGORY_96,CATEGORY_35)和产品(如PRODUCT_22735,PRODUCT_225)。

      下面我将演示如何创建一个特定对象的布局句柄功能。句柄将由对象的ID(如OUR_COOL_OBJECT_535,OUR_COOL_OBJECT_863)字符串组成。

      1、创建观察者

      为了避免增加句柄到Magento布局更新对象过晚,我们需要观察controller_action_layout_load_before时间。

      
      <config>
          <frontend>
              <events>
                  <controller_action_layout_load_before>
                      <observers>
                          <alwayly_controller_action_layout_load_before>
                              <class>alwayly_layouthandle/observer</class>
                              <method>controllerActionLayoutLoadBefore</method>
                          </alwayly_controller_action_layout_load_before>
                      </observers>
                  </controller_action_layout_load_before>
              </events>
          </frontend>
      </config>
      

      2、添加句柄

      现在我们必须计算布局更新句柄并将它添加到布局更新对象里。

      
      <?php
       
          class Alwayly_LayoutHandle_Model_Observer
          {
              public function controllerActionLayoutLoadBefore(Varien_Event_Observer $observer)
              {
                  /** @var $layout Mage_Core_Model_Layout */
                  $layout = $observer->getEvent()->getLayout();
       
                  $id = Mage::app()->getRequest()->getParam('id');
       
                  /* or */
       
                  if($ourCoolObject = Mage::registry('our_cool_object'))
                  {
                      $id = $ourCoolObject->getId();
                  }
       
                  $layout->getUpdate()->addHandle('OUR_COOL_OBJECT_'.$id);
              }
          }
      

      360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 26 Sep 2015 14:16:36 +0000
      <![CDATA[magento2中的路由]]> https://www.360magento.com/blog/routing-in-magento2/ 我们可以说路由,是Magento中最重要的部分。Magento2中完整的进程流取决于URL进程请求和路由器类(用来响应匹配和执行请求)。这篇文章包含了Magento2中路由器流并分析一些默认的路由器。当然,这里也会演示怎么去常见一个自定义的路由器,提到路由器是如何匹配到方法(控制器类),更多关于控制器的信息将会在其它文章中提到。

      路由流

      首先,我们需要分析完整的路由流,这样我们就能为后面的部分了解更多的细节。我们之前就知道,Magento2在请求启动的流类(launch method)里创建HTTP进程。我们的流以创建前端控制器开始。

      $frontController = $this->_objectManager->get('Magento\Framework\App\FrontControllerInterface');
      

      前端控制器对循环槽中所有可用的路由器和当前请求匹配的路由进行响应。稍后我们将详细讲解前端路由。现在,还是先理解整个流程,其中进程如何匹配路由器是重点。路由器列表被创建在RouterList(在前端控制器路由器循环里被调用)类里,位于Magento\Framework\App中。这个类用来排列和迭代路由器列表。路由器类负责匹配响应当前请求的路由器。让我们看看Magento2的流程。

      index.php (runs bootstrap and create HTTP application) → HTTP app → FrontController → Routing → Controller processing → etc

      现在我们将分析路由流程的每个部分以便更好地理解Magento2的路由。

      前端控制器

      和Magento1中一样,这是路由入口,被HTTP启动进程(launch method)调用。负责对当前请求路由进行匹配。它位于lib/internal/Magento/Framework/App/FrontController.php。你可以在HTTP启动方法FrontControllerInterface里找到。让我们看看这段代码吧。

      class Http implements \Magento\Framework\AppInterface
      {
          public function launch()
          {
              ...
              	//Here Application is calling front controller and it's dispatch method
              $frontController = $this->_objectManager->get('Magento\Framework\App\FrontControllerInterface');
              $result = $frontController->dispatch($this->_request);
              ...
          }
      }
      

      现在,我们知道了前端控制器何时、如何被调用,让我们看看前端控制器类(Front controller class)和它的调度方法: lib/internal/Magento/Framework/App/FrontController.php

      
      class FrontController implements FrontControllerInterface
      {
          public function dispatch(RequestInterface $request)
          {
              \Magento\Framework\Profiler::start('routers_match');
              $routingCycleCounter = 0;
              $result = null;
              while (!$request-->isDispatched() && $routingCycleCounter++ < 100) {
                  /** @var \Magento\Framework\App\RouterInterface $router */
                  foreach ($this-->_routerList as $router) {
                      try {
                          $actionInstance = $router-->match($request);
                          if ($actionInstance) {
                              $request-->setDispatched(true);
                              $actionInstance-->getResponse()-->setNoCacheHeaders();
                              $result = $actionInstance-->dispatch($request);
                              break;
                          }
                      } catch (\Magento\Framework\Exception\NotFoundException $e) {
                          $request-->initForward();
                          $request-->setActionName('noroute');
                          $request-->setDispatched(false);
                          break;
                      }
                  }
              }
              \Magento\Framework\Profiler::stop('routers_match');
              if ($routingCycleCounter > 100) {
                  throw new \LogicException('Front controller reached 100 router match iterations');
              }
              return $result;
          }
      }
      

      如你所见,调度方法将循环所有的路由器(可用的)直到一个路由被匹配,需求被调度($request→setDispatched(true);) ,或者路由计数器执行到100。路由器可以被匹配,但是如果没有调度,就会重复路由器循环。此外,路由器可以被重定向调度,或者它可以被匹配和处理。路由器列表类在请求流中被解析。现在,我们再看看路由器是如何匹配(匹配方法)的以及究竟什么是路由器。

      路由器

      简单来说,路由器就是负责匹配执行URL请求的PHP类。默认的Magento框架和核心里有些Base、DefaultRouter、Cms和UrlRewrite这样的路由器。所有这些我们都将讨论,解释它们的目标和如何工作的。路由器正在执行RouterInterface。现在让我们看看默认的路由器流:

      Base Router → CMS Router → UrlRewrite Router → Default Router (这是路由器环路—— FrontController::dispatch())

      Base Router

      Base Router位于lib/internal/Magento/Framework/App/Router/Base.php,它是环路中的第一个。如果你是magento1开发者的话,你知道它作为标准路由器。匹配方法是parseRequest和matchAction,在第二个方法中会设置前端模块名,控制器路径名,动作名,控制器模和路由名。在基础路由器中标准Magento URL(front name/action path/action/param 1/etc params/) 被匹配。

      CMS Router

      CMS Router位于app/code/Magento/Cms/Controller/Router.php,用于处理CMS页面。它设置cms模块名(模块前端名),page控制器名(控制器路径名)和view(app/code/Magento/Cms/Controller/Page/View.php)动作名。为Base controller设置好格式后,它将设置页面ID并转发这个ID,但不会调度它。转发意味着它会破坏现有的路由器循环,再次开始循环(最多可执行100次)。这个路由器循环将匹配激活View controller(Cms/Controller/Page)的基础路由器,显示被存储的页面ID(根据url找到的页面ID)。

      UrlRewrite Router

      在Magento2中,UrlRewrite有了它自己的路由器。熟悉Magento1的朋友知道UrlRewrite是Standard路由器的一部分。它位于app/code/Magento/UrlRewrite/Controller/Router.php使用Url Finder获取数据库中匹配的url重写。

      $rewrite = $this->urlFinder->findOneByData(
                          [
                              UrlRewrite::ENTITY_TYPE => $oldRewrite->getEntityType(),
                              UrlRewrite::ENTITY_ID => $oldRewrite->getEntityId(),
                              UrlRewrite::STORE_ID => $this->storeManager->getStore()->getId(),
                              UrlRewrite::IS_AUTOGENERATED => 1,
                          ]
                      );
      

      它会转向CMS router这样的动作。

      Default Router

      它位于lib/internal/Magento/Framework/App/Router/DefaultRouter.php是路由器循环的最后一个。当其它路由都不匹配的时候才使用它。在Magento2中,我们可以为"404找不到"页面创建一个自定义的句柄来展示自定义内容。下面是DefaultRouter中没有路由处理情况下的循环。

      
      foreach ($this->noRouteHandlerList->getHandlers() as $noRouteHandler) {
                  if ($noRouteHandler->process($request)) {
                      break;
                  }
              }
      

      Custom Router (附带示例)

      前端控制器会浏览所有路由器列表中的路由(由routes.xml配置创建),所以我们需要将di.xml模块中新加路由器的配置添加到lib/internal/Magento/Framework/App/RouterList.php,由此来增加自定义路由器。我们将创建一个新的模块(例:Alwayly/CustomRouter),之后我们添加心得路由器到路由器列表,最后创建路由器类。

      自定义路由器只是一个例子,在这个例子中你能了解Base router是如何匹配和跳转需求的。首先,我们需要在app/code/Alwayly/CustomRouter中为我们的模块创建一个文件夹结构,接着我们将在etc文件夹中创建modules.xml,在模块根目录下创建composer.json(带有模块信息)。现在,我们可以通过添加配置到di.xml(etc/frontend)来创建自定义路由器,这里我们的路由器只针对与前端。最后,我们将在Controller文件夹里创建Router.php来编写匹配路由器的逻辑。我们将扫描URL,确认是否有特定字,然后根据这些字简历前端模块名、控制器路径和给默认控制器的跳转请求。作为示例,我们要搜索的两个字是"examplerouter"和"exampletocms"。当搜索到"examplerouter"时,我们将跳转到Base router匹配格式(这里,我们设置前端模块名为"alwaylytest",控制器路径名为"test",动作名为"test"),当搜索到"exampletocms"时,我们通过Base router跳转到About us页面。

      di.xml(位于etc/frontend)

      < ?xml version="1.0"?> 
      < config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> 
          < type name="Magento\Framework\App\RouterList"> 
              < arguments> 
                  < argument name="routerList" xsi:type="array"> 
                      < item name="alwaylycustomrouter" xsi:type="array"> 
                          < item name="class" xsi:type="string"> Alwayly\CustomRouter\Controller\Router< /item> 
                          < item name="disable" xsi:type="boolean"> false< /item> 
                          < item name="sortOrder" xsi:type="string"> 22< /item> 
                      < /item> 
                  < /argument> 
              < /arguments> 
          < /type> 
      < /config> 
      

      Router.php (位于Controller文件夹)

      <?php
      namespace Alwayly\CustomRouter\Controller;
       
      class Router implements \Magento\Framework\App\RouterInterface
      {
          /**
           * @var \Magento\Framework\App\ActionFactory
           */
          protected $actionFactory;
       
          /**
           * Response
           *
           * @var \Magento\Framework\App\ResponseInterface
           */
          protected $_response;
       
          /**
           * @param \Magento\Framework\App\ActionFactory $actionFactory
           * @param \Magento\Framework\App\ResponseInterface $response
           */
          public function __construct(
              \Magento\Framework\App\ActionFactory $actionFactory,
              \Magento\Framework\App\ResponseInterface $response
          ) {
              $this->actionFactory = $actionFactory;
              $this->_response = $response;
          }
       
          /**
           * Validate and Match
           *
           * @param \Magento\Framework\App\RequestInterface $request
           * @return bool
           */
          public function match(\Magento\Framework\App\RequestInterface $request)
          {
              /*
               * We will search “examplerouter” and “exampletocms” words and make forward depend on word
               * -examplerouter will forward to base router to match alwaylytest front name, test controller path and test controller 
      
      class
               * -exampletocms will set front name to cms, controller path to page and action to view
               */
              $identifier = trim($request->getPathInfo(), '/');
              if(strpos($identifier, 'exampletocms') !== false) {
                  /*
                   * We must set module, controller path and action name + we will set page id 5 witch is about us page on
                   * default magento 2 installation with sample data.
                   */
                  $request->setModuleName('cms')->setControllerName('page')->setActionName('view')->setParam('page_id', 5);
              } else if(strpos($identifier, 'examplerouter') !== false) {
                  /*
                   * We must set module, controller path and action name for our controller class(Controller/Test/Test.php)
                   */
                  $request->setModuleName('alwaylytest')->setControllerName('test')->setActionName('test');
              } else {
                  //There is no match
                  return;
              }
       
              /*
               * We have match and now we will forward action
               */
              return $this->actionFactory->create(
                  'Magento\Framework\App\Action\Forward',
                  ['request' => $request]
              );
          }
      }
      

      routes.xml (位于etc/frontend)

      <?xml version="1.0"?> 
      
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd"> 
          < router id="standard"> 
              <route id="alwaylytest" frontName="alwaylytest"> 
                  <module name="Alwayly_CustomRouter" /> 
              </route> 
          </router> 
      </config> 
      

      Test.php (test controller action class)

      <?php
      namespace Alwayly\CustomRouter\Controller\Test;
       
      class Test extends \Magento\Framework\App\Action\Action
      {
          public function execute()
          {
              die("Alwayly\\CustomRouter\\Controller\\Test\\Test controller execute()");
          }
      }

      360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 26 Sep 2015 12:30:05 +0000
      <![CDATA[用magento布局给特定CMS页面添加静态块]]> https://www.360magento.com/blog/layout-special-block/ 有次在做一个项目的时候,我需要在头部和某些页面内容中间加入一个独有的静态块。元素必须完全在magento后台定义,而且能很轻易地在一个新的CMS页面创建、定义和移除。因此,元素必须被放置在主内容之外,不可能用后台CMS添加,而是要用magento布局添加。下面是我如何实现的:

      正如你所知的,magento只为CMS页面提供下面的句柄

      • 首页句柄和404页面句柄
      • 一个所有CMS页面公用的句柄

      如果一个CMS块要显示在首页,我们会在local.xml文件里使用首页句柄。同样的,如果要在所有CMS页面显示,我们可以使用所有CMS页面通用的句柄。但是,用户创建的个人CMS页面又该怎么办呢?

      幸运的是:Magento允许我们通过后台CMS编辑器为每一个CMS页面定义一个自定义布局。这样的话,一个CMS页面的布局就被数据库中为这个特殊页面定义的值修改。

      首先,我们为名为"static-block-1"特殊CMS页面创建一个静态块,加入下面的简单样式:

      <div class=”element-blue”>
              <h3>Static Block 1</h3>
              <p>This is blue static element 1 </p>
      </div>
      

      接着,我们将创建一个包含了刚才创建的静态块的CMS页面。通过这个页面的Design标签更新布局XML,里面有头部和一个段落。今天以一列布局为例。

      <reference name="root">
              <block type="cms/block" name="myelement">
                  <action method="setBlockId"><block_id>static-block-1</block_id></action>
              </block>
      </reference>
      

      最后,我们要更新我们的模板文件,添加一行调用我们元素的代码。打开1colum.phtml文件(app/design/frontend/default/你的主题/template/page/1column.phtml),按下面代码进行修改:

      …
      <div class="page">
              <?php echo $this->getChildHtml('header') ?>
              <?php echo $this->getChildHtml('myelement') ?>
      …
      

      虽然这个方法很快速,效果也不错,但是用同样的步骤添加元素会让人觉得乏味,特别是一个项目有6、7个这样的CMS页面。你觉得这个方法怎么样呢?你又是如何解决这个问题的呢?欢迎你和我们分享。

      360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 26 Sep 2015 03:35:19 +0000
      <![CDATA[如何在magento产品详细页展示video]]> https://www.360magento.com/blog/magento-product-video/ 在实际情况中,有些特殊的产品需要用video来演示。Magento商店里有不少拥有video功能的插件,但是有时这些插件因为改变了你网站的布局而不符合你的需求。读完这篇文章后你就可以在magento产品详细页的任意位置添加你需要的video。

      好了,让我们开始吧。Youtube让分享变得很简单,你只需要将video的iframe代码拷贝、粘贴到产品描述里就行了。 是不是觉得太简单了呢?那么让我们来点有难度的吧。在magento后台创建一个名为"video"的text属性(Catalog->Attributes->Manage Attributes),再将这个属性放到一个合适的产品属性集里,刷新索引(System->Index Management)。接着打开产品详细页的phtml文件:app/design/frontend/default/你的主题名/template/catalog/product/view.phtml。下面的例子中,我把video放在产品名字的下面。找到产品名字的代码:

      <div class="product-name">
           <h1><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></h1>
      </div>
      

      在下面添加这段代码:

      <?php if($_product->getVideo()): ?>
             <iframe width="560" height="315" src="http://www.youtube.com/embed/<?php echo $_product->getVideo() ?>" frameborder="0" allowfullscreen></iframe>
      <?php endif; ?>
      

      最后,我们需要把video的UID填到产品中的"video"属性框里,也就是之前添加的新属性。例如http://www.youtube.com/watch?v=U0CGsw6h60k的UID就是U0CGsw6h60k。

      还想来点更难的吗?想把video放在侧边栏?没问题。我们需要为video创建一个模块即.phtml文件。文件路径是:app/design/frontend/default/你的主题名/template/catalog/product/video.phtml。再把video放进去。代码是:

      <div class="block block-video">
          <div class="block-title">
              <strong><span><?php echo $this->__('Product Video') ?></span></strong><br>    
      </div><br>
      <div class="block-content"> <object width="193" height="130"><param name="movie" value="http://www.youtube.com/v/<?php echo $this->__($this->getLinkUrl()) ?>?hl=en_US&version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/<?php echo $this->__($this->getLinkUrl()) ?>?hl=en_US&version=3" type="application/x-shockwave-flash" width="193" height="130" allowscriptaccess="always" allowfullscreen="true"></embed></object> </div> </div>


      360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 25 Sep 2015 11:51:15 +0000
      <![CDATA[Magento模型集合常用过滤条件]]> https://www.360magento.com/blog/addFieldToFilter/         Magento的MVC模式为大家所熟悉,其中的Model作为数据处理的模型,其集合中的方法是大家开发时必不可少的。最近,我总结了下Magento模型集合中的addFieldToFilter常用过滤条件,希望对大家的开发起到一定的帮助作用。

      
      //Equals: eq
      $_products->addAttributeToFilter('status', array('eq' => 1));
       
      //Not Equals - neq
      $_products->addAttributeToFilter('sku', array('neq' => 'test-product'));
       
      //Like - like
      $_products->addAttributeToFilter('sku', array('like' => 'UX%'));
       
      //Not Like - nlike
      $_products->addAttributeToFilter('sku', array('nlike' => 'err-prod%'));
       
      //In - in
      $_products->addAttributeToFilter('id', array('in' => array(1,4,98)));
       
      //Not In - nin
      $_products->addAttributeToFilter('id', array('nin' => array(1,4,98)));
       
      //NULL - null
      $_products->addAttributeToFilter('description', 'null');
       
      //Not NULL - notnull
      $_products->addAttributeToFilter('description', 'notnull');
       
      //Greater Than - gt
      $_products->addAttributeToFilter('id', array('gt' => 5));
       
      //Less Than - lt
      $_products->addAttributeToFilter('id', array('lt' => 5));
       
      //Greater Than or Equals To- gteq
      $_products->addAttributeToFilter('id', array('gteq' => 5));
       
      //Less Than or Equals To - lteq
      $_products->addAttributeToFilter('id', array('lteq' => 5));
      

      360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 24 Sep 2015 15:45:48 +0000
      <![CDATA[magento修改后台密码]]> https://www.360magento.com/blog/change-password/        今天,我要跟大家交流的是magento后台密码的修改。在某些情况下我们需要对magento后台密码修改,那么对magento后台密码的修改有哪些方法呢?

      1. magento后台登录框左下角的忘记密码(Forgot your password?),按照提示完成密码的修改;
      2. 通过数据库修改 此方法的前提是你有数据库的访问权限!从phpmyadmin进入到网站的数据库中,打开"admin_user"这张表,找到'username'等于你用户名的那条记录。在修改密码之前,你先要准备好你的新密码和识别码,这里我以新密码:admin123,识别码AL为例。之后在网上找一个可以生产MD5的网站,将你的新密码进行MD5加密,我生成以后的结果是:7a01b04183e3534bd0a6be7ff822784e。接着回到刚才的数据表,在数据的password列,将新密码和识别码以新密码:识别码的形式插入表中。我这里的是7a01b04183e3534bd0a6be7ff822784e:AL。点击保存。稍后,你就可以用你新设置的密码进行登录了。
      3. 通过修改源码进入后台修改 此方法的前提是你有ftp的访问权限!通过ftp进入网站,打开文件app\code\core\Mage\Admin\Model\User.php,在333行左右的位置找到authenticate()方法。在
        $this->loadByUsername($username);
        这段代码下增加返回True值的代码,即:
        
        $this->loadByUsername($username);
        return true;
        
        现在你可以用任何密码进入后台了,登录后按照System->Permission->User,进入到用户管理页面。按照表格内容修改新的密码。最后,回到User.php文件,将刚才添加的代码删除。

      360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 23 Sep 2015 15:59:19 +0000
      <![CDATA[用命令操作Magento预编译的开启和关闭 ]]> https://www.360magento.com/blog/implement-magento-compiler-mode/ 提高Magento性能的一个很重要的方法是开启Magento的编译模式,可以在后台System>Tools>Compilation,点击Run Compilation Process按钮,一段时间后,我们发现Compiler Status由Disabled变为Enabled,已经编译成功了,打开/includes/src目录,会发现生成了很多文件。

      因为在Magento中,我们模块的代码可以放在/app/code/local,/app/code/community,以及/app/code/core这三个目录下,如果Magento需要包含某个文件,系统会依次搜索这三个目录,直到找到这个文件为止,这为我们重写系统的某些文件提供了方便,比如需要修改core目录下的Mage/Catalog/Model/Product.php文件,只需要复制这个文件到local目录下的Mage/Catalog/Model/Product.php,然后修改这个文件即可,这样无需修改核心文件,为我们以后升级系统提供了方便,但由于系统需要在不同的目录中搜索文件,所以效率比较低,使用Compiler功能,系统将把这三个目录下的文件按照优先级顺序复制到/includes/src目录,比如Mage/Catalog/Model/Product.php文件将复制为Mage_Catalog_Model_Product.php,这样系统能够很快的找到需要包含的文件,大幅的提高了效率。

      如果我们需要安装新的模块,或者修改已有的模块,我们需要关闭Magento的编译模式,可以在后台System>Tools>Compilation,点击Disable按钮,Compiler Status将由Enabled变为Disabled,添加或修改好模块之后,需要点击Run Compilation Process按钮重新生成编译文件。

      此外,Magento提供了一个脚本工具使我们无需进入后台就可以查看和切换编译模式,该脚本位于根目录下的/shell/compiler.php

      打开命令行,切换至shell目录:

          $cd shell
          $ls
          abstract.php compiler.php indexer.php log.php
      

      查看使用compiler.php的方法:

          $php -f compiler.php help
          Usage: php -f compiler.php -- [options]
            state Show Compilation State
            compile Run Compilation Process
            clear Disable Compiler include path and Remove compiled files
            enable Enable Compiler include path
            disable Disable Compiler include path
            help This help

      查看当前的编译状态:

          $php -f compiler.php state
          Compiler Status: Disabled
          Compilation State: Not Compiled
          Collected Files Count: 0
          Compiled Scopes Count: 0

          $php -f compiler.php compile
          Compilation successfully finished
          $php -f compiler.php state
          Compiler Status: Enabled
          Compilation State: Compiled
          Collected Files Count: 6000
          Compiled Scopes Count: 4
      

      关闭和开启编译:

          $php -f compiler.php disable
          Compiler include path disabled
          $php -f compiler.php state
          Compiler Status: Disabled
          Compilation State: Compiled
          Collected Files Count: 6000
          Compiled Scopes Count: 4
          $php -f compiler.php enable
          Compiler include path enabled
          $php -f compiler.php state
          Compiler Status: Enabled
          Compilation State: Compiled
          Collected Files Count: 6000
          Compiled Scopes Count: 4

      清除编译

          $php -f compiler.php clear
          Compilation successfully cleared
          $php -f compiler.php state
          Compiler Status: Disabled
          Compilation State: Not Compiled
          Collected Files Count: 0
          Compiled Scopes Count: 0

      我们还可以通过修改/includes/src/config.php文件开启和关闭编译模式,在编译成功后config.php将变为:

      define('COMPILER_INCLUDE_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR.'src');

      此时只需要注释掉这个语句就可以关闭编译模式:

       #define('COMPILER_INCLUDE_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR.'src');

      在Mage.php文件中我们可以看到下面一段代码:

          Mage::register('original_include_path', get_include_path()); // 保存当前的include_path
      
          if (defined('COMPILER_INCLUDE_PATH')) { // 如果设置为编译模式
              $appPath = COMPILER_INCLUDE_PATH;
              set_include_path($appPath . PS . Mage::registry('original_include_path')); // 添加includes/src为include_path
              include_once "Mage_Core_functions.php";
              include_once "Varien_Autoload.php";
          } else { // 没有设置为编译模式
              $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'local';
              $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'community';
              $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core';
              $paths[] = BP . DS . 'lib';
      
              $appPath = implode(PS, $paths);
              set_include_path($appPath . PS . Mage::registry('original_include_path')); // 添加以上四个目录为include_path
              include_once "Mage/Core/functions.php";
              include_once "Varien/Autoload.php";
          }

      我们可以发现,Magento通过检查是否定义COMPILER_INCLUDE_PATH常量来切换编译模式并设置对应模式的文件包含路径。

      ]]>
      Wed, 23 Sep 2015 12:47:58 +0000
      <![CDATA[跨境电商在中美市场碰撞火花]]> https://www.360magento.com/blog/china-america/          中国国家主席习近平23日将在西雅图出席中美商界科技论坛,在与会的中美两国各15位顶级商界领袖中,亚马逊创始人杰夫·贝佐斯和阿里巴巴创始人马云作为全球电子商务两大巨头同时出席,让为跨境电商在中美市场碰撞出火花。

              虽然亚马逊与阿里巴巴的细分目标市场并不完全一样,但两者不乏短兵相接的交叉地带。阿里巴巴在美国上市后,面对强劲对手,奋力开拓北美市场;北美电商巨头亚马逊则看准中国市场,为抢占市场份额频出高招。

        总部位于西雅图市中心、占地400多万平方英尺的亚马逊,在电子商务领域已历经风雨20载,其今年第二季度,北美销售额达138亿美元,比去年同期强劲增长25.5%。在中国市场,亚马逊瞄准消费者,近来接连亮剑,推出“海外购·直采”“海外购·直邮”“海外购·闪购”等新业务,体现对中国市场十分重视。

        亚马逊全球资深副总裁迭戈·皮亚琴帝尼近日对《环球时报》记者表示,“市场变化迅速,对亚马逊而言,应对的关键在于灵活快速地响应市场变化。中国有很强的本土电商,竞争激烈,亚马逊中国应找到跟竞争对手的区隔点、我们的优势和定位。”

        皮亚琴帝尼所说的“区隔点”,是亚马逊中国的国际品牌战略,包括目前引入亚马逊美国300万同质同价产品的“海外购”商店、进口直采、以及在此基础上今年8月推出的“海外购·闪购”创新业务。消费者不仅可以网购海外正品,更可享受全面本地化的物流配送和购物体验,商品从保税区、自贸区直接发货,平均3天就可收到订购的商品。

        产品的正品保证,是亚马逊又一与竞争对手的区隔点。亚马逊全球副总裁冯思哲对《环球时报》记者说,“中国市场发展迅速,对本土和外国电商都非常有吸引。我们在全球有专门的供应商管理团队,同时中国建立了自己的团队,团队大部分是中国人,非常了解本地市场,与全球团队紧密配合。我们在中国一直努力提供给消费者最好的正品、最好的价格和最好的配送服务。”

      据介绍,亚马逊中国的出口业务正加大力度帮助中国卖家走向全球,中国卖家已成为亚马逊“全球开店”的生力军,并取得良好的业务表现。2015年上半年,中国卖家销售额同比增长翻番。

        另一方面,亚马逊的对手阿里巴巴也毫不示弱。今年以来,阿里巴巴因为旗下网站被指涉嫌售卖假货,被欧美多家奢侈品制造商诉诸法庭。面对社会舆论对“出售假货”的指责,阿里巴巴已重拳出击,修改假货下架程序。

        同时,阿里巴巴今年还计划在美国兴建运营配送中心,构建其跨境电商平台,使中国消费者能网上跨境购物。与亚马逊有所区别的是,阿里巴巴着重构建为买卖双方提供第三方交易平台,收取2%至5%的佣金,所以在仓储基建方面的投入相对较少,因而利润空间相对高些。

              中国商务部统计显示,跨境电商在2014年的交易额达到718亿美元,同比增长44%。虽然亚马逊、阿里巴巴两巨头依然难分高下,但毋庸置疑,中国跨境电子商务行业前景看好,将吸引更多海内外商家。

             360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 23 Sep 2015 12:47:16 +0000
      <![CDATA[解决magento开启Compilation预编译网站无法访问]]> https://www.360magento.com/blog/error-compilation/ 一般来说,开启magento的Compilation预编译功能,可以使magento的访问速度提高25%。 但由于首次用这个功能操作不当,导致magento网站崩溃,网站前后台都访问不了,这已经有好几个客户遇到这样的问题了。那么下面介绍既简单又快捷的方法。

      方法一:访问phpmyadmin,进入网站数据库的core_config_data表,搜索字段"path"的值为“advanced/modules_disable_output/Mage_Compiler”的数据,如果查找出来的该条数据的表字段“value”='1',那么改成“value”='0'

      方法二: 打开/includes/config.php,手动注释掉最后两行 将

       define(‘COMPILER_INCLUDE_PATH’, dirname(__FILE__).DIRECTORY_SEPARATOR.’src’);
      define(‘COMPILER_COLLECT_PATH’, dirname(__FILE__).DIRECTORY_SEPARATOR.’stat’);

      改成

       #define(‘COMPILER_INCLUDE_PATH’, dirname(__FILE__).DIRECTORY_SEPARATOR.’src’);
      #define(‘COMPILER_COLLECT_PATH’, dirname(__FILE__).DIRECTORY_SEPARATOR.’stat’);
      

      如果 开启预编译(Compilation)后,后台插件管理(Magento Connect Manager)不能访问。 解决方法: 把 /downloader/pearlib/php 文件夹拷贝到 /includes/downloader/pearlib/php/,这样可以解决问题。

      正确的操作方法是,第一次开启预编译,要先运行预编译(Run Compilation Process),然后再开启(Enable)

      ]]>
      Wed, 23 Sep 2015 11:09:29 +0000
      <![CDATA[magento产品详细页调用系统属性]]> https://www.360magento.com/blog/magento-detail/ 电子商务平台中,产品的详细页是重中之重。一些刚接触magento不久的朋友对详细页中的一些系统属性并不太熟悉,今天我就给大家说明下magento详细页中的一些系统属性调用方法。

      magento详细页的文件路径:/app/design/frontend/default/你的主题/template/catalog/product/view.phtml

      常见的几种属性代码如下:

      简单描述(short description):

      <?php echo $this->helper('catalog/output')->productAttribute($this->getProduct(), nl2br($_product->getShortDescription()), 'short_description') ?>

      描述(description):

      <?php echo $this->helper('catalog/output')->productAttribute($this->getProduct(), nl2br($this->getProduct()->getDescription()), 'description') ?>

      产品名称(name):

      ><?php echo  $this->helper('catalog/output')->productAttribute($_product, $_product->getName(), 'name') ?>

      产品编号(sku):

      <?php echo $this->htmlEscape($_product->getSku()) ?>

      产品价格(price):

      <?php echo $_coreHelper->currency($_finalPrice,true,false) ?>

       360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 22 Sep 2015 16:00:22 +0000
      <![CDATA[兰亭集势员工大批离职,“中国外贸电商第一股”怎么了?]]> https://www.360magento.com/blog/lightinthebox-plight/ 兰亭集势对于外贸人已经很熟悉了,曾一度被模仿,尤其是很多magento公司或个人也一度仿制magento兰亭模板,而今年在 纽交所上市的“中国外贸电商第一股”——兰亭集势,看起来已经陷入资金 困境。这家公司不仅员工大批离职,与供应商矛盾也在激化。“整个部门95%的同事从6月15日至今只发底薪,提成为零。”兰亭集势北京一位在线销售告诉 《中国经营报》记者。兰亭集势每月15日发工资,2015年6、7、8月大部分员工都是只发底薪,因此员工对公司前景的悲观情绪正在加重。

      兰亭集势员工正在加速离职,该公司一个离职员工微信群的成员数已经接近500人。以该公司位于北京望京地区包含在线销售以及客服在内接近50人规模的eBay销售团队为例,2015年以来离职员工已在20人左右。

      兰亭集势在2015年6月份刚刚获得A股上市公司——奥康国际(603001.SH)大约7700万美元战略投资,为何还如此缺钱?兰亭集势(北京)科技有限公司相关部门负责人在接受本报记者采访时表示,资金状况属于商业秘密、无可回复。

      现实困境

      兰亭集势北京一位在线客服2015年6月和7月的工资条显示,其实发工资只有3200元-3500元;此前,其每月平均工资水平在7000元~8000元,每月提成在3000元~4000元,6月以来的收入水平仅相当于此前的1/2。

      据记者了解,兰亭集势销售团队按照利润计算提成,每月提成的总体规模大约为销售利润的15%,然后按照每个销售小组的排名情况以及每个员工当月的绩效考核情况,核算个人的业绩提成。

      在2015年6月的时候,发现工资少了的员工曾向人事部门询问相关情况,得到的答复是,此前几个月的工资“算错账了,所以要从今后几个月的工资中扣掉”。

      前述兰亭集势北京员工透露,从2015年6月开始,“销售部门计算利润的公式变了,说是之前运费一直算低了,所以从2015年开始到现在大家的提成为零”。

      兰亭集势一位离职管理人员认为,“应该是公司觉得提成不合理,所以重新弄了一个算法。”

      兰亭集势(北京)科技有限公司相关部门负责人在接受本报记者采访时官方否认了“只发底薪”的现象;而对于员工离职的问题,该负责人表示,每个公司都有离职员工,这是正常情况。

      增收瓶颈

      成立于2007年3月的兰亭集势,基本商业模型是:跨国B2C,用Google推广,用Paypal支付,用UPS和DHL发货。其实,就是通过自有电商平台,也通过在eBay和亚马逊等海外电商平台上开店的方式,将中国商品卖到海外市场,当然主要是北美和欧洲市场。

      兰亭集势在经历徐小平等人的天使投资,又经过2008年500万美元、2009年1127万美元、2010年3500万美元三轮融资后,于2013年6月6日登陆纽约交易所。

      背靠着“世界工厂”的中国,头顶着“中国外贸电商第一股”的光环,兰亭集势IPO发行价为9.5美元,第一个交易日收盘价为11.61美元;在上市初期的连 续7个交易日,兰亭集势一举涨到16.98美元,较发行价涨幅达78.73%;该公司股价在2013年8月曾经触及最高点23.38美元,此后一路下跌, 截至2015年9月8日的收盘价为2.96美元,仅相当于发行价的31%,为上市以来最低值。

      股价低迷的背后,是兰亭集势收入增速大幅放缓、支出大幅增加、亏损幅度不断扩大的现实。

      对 于增长乏力、亏损扩大的原因,兰亭集势内部人士认为,没能找到新的卖点是兰亭集势收入增长乏力的主要原因,虽然一直在尝试把安防等电子产品发展成为新卖 点,但目前的主打产品仍然是创业时期以婚纱为代表的服装产品,服装品类在净营收中的占比还在40%左右。数据显示,在2015财年第一季度8760万美元 的净营收中,3170万美元的服装品类占比达36.18%。

      一位国内电商人士分析,商品定位和品牌定位决定了其只能卖低毛利产品,然后花费大把的营销费用去做搜索引擎营销;除此以外,兰亭集势近几年没有储备优势资源,没能建立自己的行业壁垒,失去了发展机遇。

      另一位内部员工表示,兰亭集势主要是把廉价国产货卖到海外,要想赢得回头客难度很大,所以只能拼命打广告、拼流量,这只能让营销成本居高不下。

      外部压力

      增收瓶颈、资金困境之外,兰亭集势在自身所处的跨境B2C出口电商业务领域也面临越来越严峻的外部竞争。

      前 述国内电商人士认为,相对于国内电商平台而言,亚马逊中国凭借海外市场上无人能比的电商网络与渠道,在面向中国企业的跨境出口电商业务领域显然拥有更多、 更大的优势;只要亚马逊中国能够解决物流问题,能让国内出口企业通过其平台上规模即可获利,而不是利润被物流吃掉,其前景不可小觑。

      阿里巴巴B2C模式的全球速卖通在强大资本支持下已经迅速成为中国跨境出口电商领域的老大。

      “阿里巴巴鼓励卖家直接从淘宝搬过去做外贸,所以在其他跨境电商平台上还没看到的产品种类,速卖通已第一时间与淘宝同步。”上述电商人士表示,速卖通不仅抢到了客源和新兴市场,而且占领了更多的品类,这就是平台的优势,同时也推高了广告费用、增加了竞争对手的反击门槛。

      数据显示,兰亭集势2014财年的订单总量达到970万份,而速卖通在2014年“双11”期间的总订单数就超过680万份。上述电商人士认为,如果兰亭集势不能在热卖品类或者优势资源上形成独特优势,那么肯定会越来越边缘化。

      为了塑造自身优势,兰亭集势已于2015年年初推出“兰亭智通”全球跨境物流开放平台。但兰亭集势内部人士担心,自建物流的结果可能使该公司资金上承受更大压力,“京东为什么一直亏,就是因为不断自建物流”。

       360magento提供专业的基于magento系统的跨境电商平台网站开发和托管服务,如有需求或相关咨询,请与我们联系

      ]]>
      Tue, 22 Sep 2015 14:11:05 +0000
      <![CDATA[SEO 也分三层境界]]> https://www.360magento.com/blog/seo-three/ 没有人会手把手教你创业,别人没这个义务,很多东西你必须自己去研究。

      流量获取的通道,就大方向而言,包括广告采购,搜索优化,社交营销,广告采购最大的一块是 SEM,其他还有很多;搜索优化目前包括 SEO 和 ASO,前者是针对搜索引擎,后者针对各种移动市场,但其实只要涉及搜索的平台,包括淘宝在内,都有搜索优化的空间。社交营销主要平台是微博,微信,朋友圈,陌陌等,海外是 Facebook,Twitter,YouTube,Instagram,以及 Snapchat 等。

      SEM 这块,很早之前 Google 和百度的广告系统还不够完善的时候,有很大的空子可以钻,2004年 吴京川老师(百度元老,百度联盟的创始人,最早发现 hao123 巨大价值的人,当年我做统计系统也是受他影响和指点)讲 Google SEM 搜索套利模式的时候,我听的一愣一愣的,完全没听懂,等 2007年 我听明白的时候,这个市场已经过去了。简单点说就是,寻找 Google 搜索广告中价格被低估而转化效果好的长尾词,买这些广告,但不用做网站,直接放 ebay 的效果广告,说白了就是替 eBay 买 Google 的广告,但是如果你数据玩的好,对转化率跟踪比较做的透,就可以赚钱,这个生意有多大呢?有个公司靠做这个后来卖了几个亿美金(有意思么,那时候几亿美金绝对不是小数字,但是国内的媒体上基本没人报)。但随着 Google 和百度广告系统的不断完善,这个空子基本没有了。

      目前依靠 SEM 的很多是跨境电商,典型如做到上市的兰亭集势,此外香港上市的 dx.com。不确定对 SEM 的依赖度高不高。 想要具体了解 SEM 的有关数据,semrush.com 是一个非常不错的数据网站。

      下面说一下 SEO,很多人对 SEO 有一种误解,认为追寻 SEO 就是骗取搜索引擎流量,是不入流的做法,特别是一些精英背景的创业者,往往听到 SEO 就嗤之以鼻,这是非常不对的。

      SEO 我讲过,分三层境界,获得热门词的前几名,是第一层境界,也就是大部分人对 SEO 的理解,提升搜索引擎的收录和权值,让网站在搜索引擎中有非常多的收录,每天获得大量的长尾词来路,是第二层境界,也是通常一些专业 SEO 服务公司的目标。而第三层境界是,让自己的品牌词成为热门词,在指数上有显著的体现,达到这一境界,你就不用担心搜索引擎会封掉你的站,典型如淘宝,很早就主动屏蔽了百度的蜘蛛,但是每天通过品牌词从百度搜索过去的用户多达数百万,这就是品牌的极端案例。

      下面说几个关于 SEO 比较成功的案例,先说重量级的,在上市公司里,汽车之家是非常非常重视 SEO 的一个典范,58 同城和赶集网当年在 SEO 上的争夺和投入都是非常巨大的,此外,同程旅游网对外接受采访的时候也公开说 SEO 是他们的核心竞争力。看到这些案例,还会觉得这是小儿科的东西么?

      未上市公司里,4399 的品牌强度是首屈一指的,去年估值几个亿卖掉的欣欣旅游早期在 SEO 优化上也是成绩斐然,当时著名站长夏天天给他们做过一次培训,边悦同学贯彻和操盘了优化的过程,(边悦后来自己出去创业,是个典型的实用主义创业者,靠 SEM 赚的风声水气,当然,媒体上看不到他。)

      另外两个值得一提的案例,一个是麦包包,一个是名鞋库。这涉及一个 “出淘” 的概念,很多淘品牌发现淘宝上运营成本越来越高,对淘宝依赖性越来越强,所以很多商家也希望自建官网,减少对淘宝的依赖度,但是官网流量和用户哪里来?在移动互联网到来之前,只有百度是最大的流量入口,但大部分淘品牌,自建官网的流量运营并不顺利,而麦包包和名鞋库则是两个非常成功的范例,在三年前的样子,麦包包是所有淘品牌里百度指数最高的一个,而且是遥遥领先于所有其他淘品牌,操盘手是柳焕斌,柳焕斌离职后,目前似乎已经不再具有如此明显的领先优势,有兴趣的同学可以到百度指数上查询一下,时间轴拉长,对比麦包包和其他淘品牌关键词,看看当年的趋势变化。名鞋库我记得在 11年 还是 12年 的时候,当时每天百度来路只有 1000 多而已,我跟他们市场副总裁韩步勇一向关系不错,还拿这个取笑过他们,但转年人家知耻而后勇,定下了每天百度来路 6 万的指标,通过和刑天 SEO 团队的深度合作,到年底的时候,竟然真的实现了。成为所有鞋类电商百度来路最多的平台,是的,超过了好乐买,也超过了当时的乐淘。仅此一项,每年节省广告费数千万,形成销售额数亿。而成本真的并不高。

      SEO 这个话题如果扯开实在太大,有兴趣的同学,除了多去看百度指数,百度热榜外,建议学习使用 aizhan.com,我前几年几乎每天都在 aizhan.com 上分析关键词,分析竞争对手的搜索来路构成。

      说一个观点,我们天天讲产品要满足用户需求,什么是用户需求?产品经理拍拍脑袋就是用户需求么?为什么用户会去搜索引擎搜索?搜索行为不就是用户需求么?搜索的频率不就是需求的强度么?按照用户的搜索词频度去设计网站,定义网站的架构,不就是满足用户需求么?你连用户搜索行为都不分析,摆出一副高高在上,我只关心用户,不关心搜索的态度,你真的关心的是用户么?

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 21 Sep 2015 15:59:43 +0000
      <![CDATA[谷歌:下一个十年 跨境电商路在何方?]]> https://www.360magento.com/blog/next-step-ecomerce/ 9月19日,2015第五届中国跨境电商大会暨海贸会5周年在广州召开。Google出口业务总经理黄秀兰出席并与现场嘉宾分享了Google对跨境电商未来趋势的解读。她提到,市场洞察、数据分析、营销策略将在未来跨境电商领域的竞争中起到越来越重要的作用。

      10年前的2005年,中国外贸电商的一个重要品类——婚纱悄然兴起。在著名的虎丘婚纱一条街,几十元到一两百就能买到相当不错的婚纱,而欧美市场的一条婚纱价格至少在三五百美金以上。巨大的价差促成了一大批企业通过网络将婚纱卖到海外,赢得了外贸电商的第一桶金。

      十年来,互联网已成为跨境电商发展的重要驱动力。Google作为全球互联网行业的先行者,坚持为中国的企业提供前沿的数字营销理念以及全方位的数字营销解决方案和服务,帮助中国企业精准定位国际市场,推动中国跨境电商的整体成长。

      全球与“进出口”相关的搜索中,中国拔得头筹

      十年来,跨境电商也逐步从小打小闹的作坊式生意开始向资本市场靠拢。2007年成立的兰亭集势,2013年登陆纽交所。2014年,百圆裤业10亿元收购跨境电商环球易购,后来改名为跨境通,市值接近200亿。

      从07年至今,在Google上与“进出口”相关的搜索中,中国最受关注。这体现了世界对一个国家进出口的关注程度。在过去几年中,“中国”很明显的形成了一条上扬的曲线。它的关注度,是位于第二名的美国的八倍之多。

      下一个十年,跨境电商路在何方?

      通过对数据的分析,Google提出未来十年跨境电商的五大趋势和变化,而其中有一些变化正在发生。

      趋势1: 从卖给“所有人”到卖给“一些人”

      从卖给“所有人”到卖给“一些人”,即定位的变化。在跨境电子商务刚刚兴起的几年里,海内外价格差是选择商品的唯一信号。那个时期的网站,从热卖商品到网站设计,再到季节性促销,都出奇的一致。一个网站里基本也集合了所有热卖商品,婚纱,手机,配件,水龙头,奇怪地组合在一起。“卖给所有人”的时代正在远去。

      如今的跨境电商已进入一个精细化、垂直化竞争的时代。目标群体的定位也越来越清晰。他们喜欢什么,喜欢什么时候买,都要能了如指掌。

      趋势2: 从大规模制造到小规模定制

      在“工业4.0”时代,物联网、智能化等新技术正在提高制造业水平,制造业正向智能化转型,用户需求决定生产制造,传统供应链向柔性供应链转变。

      以服装业为例,以前衣服从设计到打版、定型,需要半年的时间,然后采购物料,进入生产流程,到进入流通渠道,基本需要20个月。近年来,“快时尚”风靡全球,它反映在对潮流的快速响应,从捕捉时尚潮流到将产品送到消费者手中所用的时间短。这样的生产方式,便于企业迅速收集市场反馈数据,并基于数据做进一步的产品发展决策。受互联网影响的小而快的生产模式正在对制造业产生更深刻的变革。甚至可以在用户需求明确以后才进行生产。现在50件起订,7天快速生产的服装企业正应运而生。

      趋势3:从卖白牌到卖品牌

      如果过去十年,主要竞争的是山寨、无品牌产品,那么跨境电商的下一个十年将进入品牌的竞争,未来最终会进入一个跨境电商的品牌时代。小而美的品牌将会在跨境电商竞争中拥有重要的位置。

      以服装行业搜索行为变化为例。服饰类一般关键字的搜索基本比较平稳,主要是季节性的波动。而品牌关键字的搜索却直线上升。2007年服装类的热门搜索词中,每300个搜索中会有1个中国服装的网站,而到了2015年,每10个搜索就有1个中国服装网站品牌。

      趋势4: 从硬广告到软沟通

      从营销的角度看,未来最重要的一个趋势就是,广告正在消失——那些旗帜鲜明的“硬广告”正在消失,广告正在以“沟通”的形式融入到你的生活。在移动时代,无论何时何地、遇到何种状况,人们通过使用手机即时解决问题的时刻;也就是消费者产生学习、探索、观看、查找或购买意愿时,习惯于通过智能电话这类最贴身的移动设备达到目的、满足需求的时刻。

      在过去,消费者将其转变为现实需要经历几天、几个星期甚至几个月的时间;因此过去的市场营销人员设计、从事营销活动时更专注于培养消费者的品牌意识和忠诚度,希望他们从购买意向到购买决定之间能够以此为导向。而当今的消费者从产生消费需求到实际购买可以在很短的时间内完成,这一瞬间就可能导致整个营销活动的成功或失败。

      趋势5: 从卖欧美到赢全球

      未来十年,跨境电商将真正走向全球。跨境电商在过去的竞争主要集中在欧美英语市场,但未来的竞争格局会大不同。在零售电商领域,亚太区的销售额现已超越美国和欧洲,位居全球第一。而拉丁美洲、中东等区域,他们的增长率将在2020年达到30%,是美国和欧洲的两倍。

      据统计,跨境电商的主要投资市场和投资幅度增长最快的市场有显著不同。他们的投资市场,除去美国,澳大利亚,加拿大之外,还有三个最大的欧洲市场以及一些亚洲市场。而从增长最快的市场来看,中东地区占据着显著的位置。在前五名中,就有三个是中东国家,且增长率超过100%。

      由此,过去的跨境电商竞争基本是以廉价商品、粗放竞争为主。而现在,跨境电商的竞争已经转型,市场洞察、数据分析、营销策略将在竞争中起到越来越重要的地位。为了更好的服务中国的跨境电商企业,Google在五年前设置了专门的“Google 出口顾问”来为客户提供深度市场分析,网站用户体验咨询以及营销方案优化。下一个十年,Google也将和更多的企业携手同行,迎接新的挑战。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 21 Sep 2015 15:27:40 +0000
      <![CDATA[亚马逊将于2016年6月关闭网店建站服务]]> https://www.360magento.com/blog/amazon-webstore/ 亚马逊Amozon已正式对外公布将关闭网店建站业务webstore,在未来一年多的时间里,卖家们需要找到新的服务替代者,其竞争对手如加拿大电商Shopify和澳大利亚电商初创公司Bigcommerce将有望获得更多的客户。亚马逊公司未对外透露关闭该业务的原因。

      从外媒“recode”3月18号的报道中获悉,亚马逊已通知各线上卖家,亚马逊Webstore服务将于2016年6月1日关闭。在此项服务取消之前,亚马逊公司的客户们将有一年多的时间寻找新的服务商。

      由于新公司如加拿大电商Shopify和澳大利亚电商初创公司Bigcommerce已经募集到了足以扩大业务和吸引更多客户的风险投资资金,面向中小企业的电商软件业务将面临愈加剧烈的竞争环境。不少朋友可能会记起,在去年夏天,eBay公司宣布中止提供面向小型网店的产品Magento Go,并建议他们将业务转到Bigcommerce。

      亚马逊的卖家们也渐渐得知了这一消息。由于亚马逊的发言人拒绝对此置评,亚马逊此举的动机尚不得而知。畅路销(ChannelAdvisor)首席执行官Scot Wingo表示,畅路销已经开始建议一些卖家撤离亚马逊网店平台。Scot Wingo说:“我们将协助大约百名在使用亚马逊平台的客户将业务过渡到其它电商平台,如Shopify、Bigcommerce,、Mozu和Magento等。好消息是,作为库存管理和订单配送中心,我们可以为客户实现无缝对接。”

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Mon, 21 Sep 2015 02:44:42 +0000
      <![CDATA[Magento 简化URL]]> https://www.360magento.com/blog/simplify-URL/ Magento模板开发中,有时候需要将多级分类的url简化,Magento的URL默认是显示多级分类的

      例如:http://www.360magento.com/分类1/分类2/分类3

      现在需要简化为:

      分类2的URL为:http://www.360magento.com/分类2

      分类3的URL为:http://www.360magento.com/分类3

      具体修改方法如下:

      打开app/code/core/Mage/Catalog/Model/Url.php这个php文件,找到如下代码:

      if (null === $parentPath){ 
      $parentPath = $this->getResource()->getCategoryParentPath($category);
       }
      elseif ($parentPath == '/'){ 
      $parentPath = ''; 
      }
      

      把上面的代码注释,即:

      
      //if (null === $parentPath){
      //$parentPath = $this->getResource()->getCategoryParentPath($category); 
      //}
      //elseif ($parentPath == '/') { 
      //$parentPath = ''; //}

      $parentPath = $this->getResource()->getCategoryParentPath($category); 是获取分类的父级分类,

      下面将父级分类设置为空则在生成的URL中屏蔽掉父级

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 20 Sep 2015 10:56:34 +0000
      <![CDATA[力推金融与跨境电商融合]]> https://www.360magento.com/blog/finance-cross-border-ecommerce/          9月19日,由自治区商务厅、防城港市政府共同举办的中国-东盟金融跨境电商合作与发展论坛在南宁举办。

        论坛围绕“一带一路”背景下金融与跨境电子商务如何结合发展等相关议题展开。自治区商务厅表示,目前在东南亚零售总额中,电子商务份额还不足1%,而中国、欧洲和美国已达到6%至10%。随着互联网普及率的上升,预计在未来几年,东南亚在线零售将增长25%,广西发展面向东盟的跨境电子商务拥有广阔的市场空间。面向东盟跨境电子商务的快速发展必将带动跨境支付、金融快速发展。尽快完善跨境电商的生态体系,将为中国-东盟特别是广西和东盟的跨境电商合作提供有力支撑。

        据介绍,2014年9月南宁获批成为国家跨境贸易电子商务服务试点城市。今年以来,一批中国-东盟跨境电商平台正式上线,与泰国、越南、新加坡、马来西亚等东盟国家建立了良好的合作关系,广西跨境电子商务企业正在不断发展壮大。

        论坛上,专家学者和企业代表就中国-东盟跨境电商市场分析与政策解读、地方政府如何推动当地“互联网+”电商发展、重构跨境电商与农产品流通业态、跨境电商综合金融服务助力企业发展、人民币强势背景下跨境电商货币结算等议题发表真知灼见。大会还安排了电商企业项目推介、金融机构融资服务专题推介,举行了阿里巴巴1688进口货源平台·防城港站上线仪式,这是“电商入桂”的又一重要成果。

             360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 20 Sep 2015 10:11:19 +0000
      <![CDATA[首批区级电商重点培育名单出炉]]> https://www.360magento.com/blog/district-level-ecommerce/ 日前,记者从区商务局了解到,第一批萧山电子商务产业重点培育企业名单正式出炉,7家电商企业榜上有名。据悉,本次认定的企业包含5家电子商务企业和2家电子商务服务企业。

        电商行业巨头

        近日,国内知名医药巨头康恩贝与浙江珍诚医药在线股份有限公司达成合作协议,此番两大企业的强强联合,被业内誉为线下实体品牌与线上流通渠道的完美结合,有望重新定义医药电商行业。

        而对珍诚医药来说,此次引入康恩贝战略投资,将进一步充实公司现金流,加速产业链布局。据悉,珍诚医药目前正处于高速扩张阶段,这其中包括建设现代物流基地、推进药联5万家项目等。

        珍诚医药是萧山首批区级电商产业重点培育企业之一。除珍诚医药外,此次入选的其他6家企业分别是:杭州维卓电子商务有限公司、九州通集团杭州医药有限公司、杭州卡当礼品有限公司、浙江胜利羽绒制品有限公司、杭州珍诚网络科技有限公司、杭州精纱信息技术有限公司。

        根据相关评选标准,入选的电子商务企业要求从事网络销售,年网络交易额在2000万元以上,电子商务服务企业从事代运营等相关配套支撑服务,年业务收入在500万元以上。

        此外,入选企业通过第三方平台或自建网站平台等形式,进行网上交易业务2年以上,或为电子商务产业发展和应用提供相关配套支撑服务2年以上。

        据悉,电子商务产业重点培育企业每年认定一批,一经认定有效期为3年,期满后企业需要重新提出申请。

        站上“互联网+”风口

        “从评选条件不难看出,这些企业都有一个共同点,那就是在电商行业扎根时间较长,经济效益、社会效益已经初步显现出来。”萧山区内相关负责人表示,当前电商行业成为一大主流,很多企业纷纷涉足,但至于怎样做才更有效,这7家企业的商业模式或对其他企业具有一定参考价值,“这也是评选首批电商重点企业的意义所在。”该负责人说。

        特别是,当前“互联网+”风起云涌,各个行业各个企业都在积极对接“互联网+”战略,尤其是萧山的一大批传统优势企业,更是积极投身其中,通过触网拓展销售渠道,创新商业模式,推动业务结构转型升级。

        比如说浙江胜利羽绒制品有限公司,这家以出口羽绒被为主的传统生产型企业,在国内站稳脚跟之后,目前还在日本注册了电子商务公司,准备开展跨境电商业务。据悉,胜利羽绒的跨境电商业务即将上线。

        而另一家企业杭州卡当礼品有限公司,主打创意个性礼物定制,其产品线囊括了时尚饰品、珠宝手表、鞋包配饰等数十个大类超千款产品。事实上,该公司销售额连续多年保持了近300%的增幅,并在个性礼品定制行业处于第一品牌的优势地位。

              360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sun, 20 Sep 2015 10:09:18 +0000
      <![CDATA[京东云互联网+质检]]> https://www.360magento.com/blog/jd-internet/ 9月16日,第三届国际检验检测技术与装备博览会在北京雁栖湖国际会议中心正式开幕。开幕式上,京东集团与中国出入境检验检疫协会举行了战略合作签约仪式,将共同打造中国电商产品质量云平台。

      京东集团副总裁何刚与中国出入境检验检疫协会副秘书长段小红签署了战略合作协议。国务院参事、中国出入境检验检疫协会葛志荣会长,国家质检总局项玉章总检验师,中国出入境检验检疫协会鲍俊凯秘书长,中国检验认证集团齐京安董事长等高层领导也出席了签约仪式。据悉,双方未来将在以下三个领域重点展开深入合作。

      一、推进建立行业标准,共同打造生态体系

      双方将共同发起并制定电子商务产品质量标准,推动建立电子商务产品认证和企业质量信用评价体系,并通过电子商务产品质量追溯体系,建立以组织机构代码和商品条码为基础的电子商务产品质量追溯制度。依托京东云计算和大数据技术,随着业务与数据的深入整合,双方将打造全新的电商产品质量生态体系。

      二、盘活检验检测存量数据,实现数据价值真正增值

      双方将借助京东云计算服务构建社会化的进出口商品质量信息库和质量信息服务平台,并将其与商品大数据追溯系统、电子商务产品质量信息公共服务平台进行系统整合与优化,利用京东大数据分析系统和算法模型、数据挖掘等分析技术,将进出口商品的信息数据、商品标准、认证信息、许可信息等数据进行分析整合,从而充分展现质量数据和信息的实用价值,为企业和消费者提供更多的便利和保障。

      三、推进电商产品质量提升,服务生态企业和消费者

      借助京东云计算服务实现对电商产品质量状况的在线监测,通过京东大数据分析技术提升电商产品质量信息服务平台的应用能力,为政府监管部门、电商企业、广大消费者提供安全、便利的商品质量信息服务。进而全面提升企业进货质量的把关能力,为消费者提供产品质量标准方面的解读服务,让消费者直观地了解产品质量标准,区分产品质量优劣,实现“源头可溯、去向可查”。

      何刚表示,双方将建立长期的战略合作关系,充分发挥各自的资源优势,推进建立健全的电子商务质量管理制度规范,在电子商务领域营造人人重视质量、人人创造质量、人人享受质量的社会氛围,共同提升中国电子商务企业的质量保证能力,净化并提高电子商务产业的质量发展环境。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 19 Sep 2015 02:15:45 +0000
      <![CDATA[2015中国-东盟电子商务峰会开幕]]> https://www.360magento.com/blog/2015-asen-ecommerce/ 9月18日,2015中国-东盟电子商务峰会在南宁开幕。峰会以“互联网+新战略,中国-东盟新经济”为主题,来自中国和东盟国家政要、重要商协会负责人、著名经济学家、电商领军企业家和各界代表结合“中国-东盟互联网+新经济”、“中国-东盟跨境电商新基地”、“中国-东盟经贸信息港展望”和“中国-东盟创新创业新机遇”四大议题开展主题演讲及高端对话,现场气氛活跃,反响热烈。

      大会指出,“互联网+”对形成新的经济增长点、促进国际产能合作、推动区域经济一体化有重要意义。广西将秉持开放合作、互利共赢的精神,以打造中国-东盟跨境电商基地为目标,推动中国-东盟经贸信息港建设,与东盟各国朋友一道,共商、共建、共享21世纪“电商丝路”,为打造中国-东盟自由贸易区升级版和中国东盟命运共同体进行探索和努力。

      “广西是面向东盟的前沿和门户,是离东盟最近的省份。广西和东盟是山水相连、地缘相近,联系非常密切,做电商得天独厚。”除了地域优势,广西商务厅参会领导表示,发展电商,特别是跨境电商,特别需要人,特别是东盟10国语言不同,小语种的人才非常稀缺。广西是小语种人才的培训基地,这方面广西有非常大的优势。此外,中国-东盟信息港正式落地南宁,中国-东盟信息港将要建设经贸信息港,打造电子商务云中心,利用信息中心、交流中心、商务会展中心,这些都是为电商发展提供了条件。

      菲律宾参会嘉宾表示,广西与菲律宾的合作非常有潜力。今天有相当多的电商企业来参加会议,这些电商本身有一个非常好的平台,并且他们也志在进入菲律宾市场,所以广西在合作进程当中占有一个非常重要的作用。

      本届峰会促成了一系列合作,广西“互联网+”产品二维码中心建设、广西商务厅与苏宁云商战略合作、东兴市与京东集团华南区关于电子商务进农村示范工程战略合作等一批重大合作项目落地广西发展。

      据了解,9月19日,峰会还将举办中国-东盟电商领袖交流会、中国-东盟电商创业交流会、中国-东盟金融跨境电商合作与发展论坛等一系列活动。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 19 Sep 2015 02:09:11 +0000
      <![CDATA[告别传统搜索模式,移动电商进入场景化发展新时代]]> https://www.360magento.com/blog/mobile-ecommerce/ 移动互联网的快速发展以及智能终端的普及,培养了用户扫一扫、查一查身边出现的一些商业广告的习惯,甚至可以触发用户于“不经意”间完成一次网上购物。研究表明,66%的智能手机用户会通过手机查询旅途中、就餐中看到的商业广告的信息。

      在腾讯移动事业群副总裁马斌看来,人们的购买方式正在由传统化向碎片化转变,支付方式由PC端转到移动端,随时随地购物的消费需求日益迫切。在这个过程中,“无需搜索,按需推送”的场景化服务应运而生。

      “纵观国内电子商务市场,”业内人士认为,“场景化或将可以撬动本地生活服务电商领域的亿万商机,成为移动电商发展新方向。”具体说来,原因主要有以下两点:

      一、移动互联网时代,场景触发消费者购物欲

      近年来国内电商呈现蓬勃发展之势,并先后经历了电商的搜索时代和流量时代。但不管哪个阶段,消费者的购买方式始终是具有目的性的,并且必经此流程:目的——搜索——选择——购买。但是科技的飞速发展,为消费者带来了更加便捷的购物体验。

      以消费者买包为例,按照传统流程首先是广泛搜索,在某个商城网站通过品牌、种类来锁定某款样式;其次,看看这个包是不是时尚,是不是符合自己的个性,是不是性价比很高;然后还需要看看有没有人购买,有没有人评论;最后综合考虑进行决策。购买决策时间长,甚至还会为某种原因最终放弃购买,电商平台并不能了解到用户所处的购买场景。

      如果电商网站或者店铺提供了以上这些足够丰富的场景化信息,比如消费者进店后立即推送相应的折扣优惠,那么便会直接激发出购买欲望,迅速作出购买决策。这就是商家给消费者构建了一个场景,通过这个场景来触发消费。

      事实上,“场景”是一个非常重要的词,产品和营销必须基于消费者具体、特定和鲜活的场景,研究消费者场景可以发现新产品机会,制造消费者场景可以开辟新产品空间,展示消费者场景可以驱动消费者的购买行为。

      然而很多时候,一些电商网站和电商店铺并没有关注这一点,良好的客户体验一定是基于消费者的生活场景的,在商品促销中没有生活场景,对于消费者而言就是冰冷的,有生活场景就是可以被打动的。

      二、场景化可以更好提高电商交易转化

      “场景触发不只是为了推送信息,更希望用户产生回单和复购,这是非常重要的。”业内人士认为。

      在传统购物中,刷卡、现金结算往往意味着商家与消费者的关系结束,用户粘性的缺乏使商家很难形成二次消费;但在场景服务中不一样了,商家如果能够通过智能手机的传感器WIFI/ibeacon等设备定位和触发,获知用户的具体位置场景,通过对用户行为数据的收集和分析建立起对他们的画像,就可以达到个性化、精准、前置信息的推送。不但为商家提升进店率、留存率、转化率带来了可能;这时,信息推送也不再被认为是骚扰,而是商家及时贴心的服务。

      举例来说,当小编携带安装爱街“WiFi密探”的手机,来到望京凯德MALL,在闲逛路过“太平鸟”专卖店门口时,手机上就会收到“太平鸟”天猫旗舰店的新款推荐,可以和实体店比比价格和款式,点击就可以在手机上下单购买。场景购物,体验真好!

      目前,万达电商“飞凡网”、阿里的“喵街”、迈外迪、爱街、鲜老虎等众多企业正在进行线下场景布局,通过营造更轻松、更智能、更个性化的购物体验,让顾客和商家建立长久关系。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Sat, 19 Sep 2015 01:55:37 +0000
      <![CDATA[Magento通过分类搜索产品功能]]> https://www.360magento.com/blog/magento-categpry-search/ 想要magento站点搜索加上分类选项,只需要在magento相应的模板中,用以下代码替换app/design/你的主题名/template/catalogsearch/form.mini.phtml文件中的源代码即可。然后刷新索引和缓存,你将会发现搜索的旁边出来一个分类选项!

      
      <?php
              $category = Mage::getModel('catalog/category');
              if(is_object(Mage::registry('current_category'))){
                  $current_category_path=Mage::registry('current_category')->getPathIds();
              }else{
                  $current_category_path = array();
              }
              $category->load(Mage::app()->getStore()->getRootCategoryId());
              $children_string = $category->getChildren();
              $children = explode(',',$children_string);
              $extra_options='';
              foreach($children as $c){
                  $selected = (in_array($c, $current_category_path))?'SELECTED':'';
                  $extra_options.= '<option value="' . $c . '" ' . $selected . '>' . $category->load($c)->getName() . '</option>' . "\n";
              }
              ?>
              <form id="search_mini_form" action="<?php echo $this->helper('catalogSearch')->getResultUrl() ?>" method="get">
                  <fieldset>
                      <legend><?php echo $this->__('Search Site') ?></legend>
                      <div class="mini-search">
                          <input id="search" type="text" class="input-text" name="<?php echo $this->helper('catalogSearch')->getQueryParamName() ?>" value="<?php echo $this->helper('catalogSearch')->getEscapedQueryText() ?>" />
                          <select name="cat" id="cat" class="input-text">
                          <option value="">All Departments</option>
                          <?= $extra_options ?>
                         </select>
                          <input type="submit" value="Go" style="border: 1px solid #808080;" alt="<?php echo $this->__('Search') ?>" />
                          <div id="search_autocomplete" class="search-autocomplete"></div>
                          <script type="text/javascript">
                          //<![CDATA[
                              var searchForm = new Varien.searchForm('search_mini_form', 'search', '<?php echo $this->__('search site...') ?>');
                              searchForm.initAutocomplete('<?php echo $this->helper('catalogSearch')->getSuggestUrl() ?>', 'search_autocomplete');
                          //]]>
                          </script>
                      </div>
                  </fieldset>
              </form>

              360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 18 Sep 2015 08:15:30 +0000
      <![CDATA[PayPal 2015中国外贸电子商务大会推出升级电商+解决方案]]> https://www.360magento.com/blog/2015-paypal/ PayPal今天在深圳举办了其第四届中国外贸电子商务大会,与800多名大型及中小型外贸电商、政府代表以及行业嘉宾一起探讨了全球跨境电商市场的新趋势、新机遇,共同促进中国跨境电商市场的繁荣发展。今年,PayPal 在大会上隆重推出了“PayPal电商+”创新解决方案,瞄准B2B2C (国内企业卖家→国外企业买家→国外消费者) 出口模式的巨大潜力,引领电商升级,共享全球机遇。

      挖掘跨境电商市场的新趋势、新机遇

      中国跨境电商市场增速迅猛,截止2014年其市场规模已突破4万亿元,预计到2017年底规模将实现翻一番。其中,外贸B2B(企业对企业) 模式是首要驱动力,占跨境电商整体市场份额高达80%。B2B2C蕴含大量机会,成为本次大会的焦点。

      “跨境电商市场充满商机,但纵观整个行业和我们的调查结果,我们发现对于中国商户来说,>外贸B2B2C模式领域拥有独特机遇——即把产品出口给面向终端消费者销售的国外企业买家。作为全球最受信赖的电子钱包,PayPal拥有无可比拟的全球闭环网络,帮助中国商户把握机遇。” PayPal中国区跨境业务总经理胡柏迪表示,“我们此次推出电商+创新解决方案,再次体现了PayPal对中国商户的承诺,通过持续创新,帮助他们应对商业挑战,在快速发展的电商市场中拓展海外业务。

      PayPal调查显示,信任程度、交易便捷性和安全风险是买家和卖家双方进行跨境电商交易过程中的主要痛点,同时也是B2B2C电商市场发展面临的普遍挑战。PayPal根据中国商户的反馈,推出了“PayPal电商+”解决方案,通过以下一系列产品及服务,帮助中国商户应对挑战:

      • 新升级的卖家保障:PayPal卖家保障为合格的商户免费覆盖多种风险损失,包括如果买家因未经授权付款和“物品未收到”而提出补偿申请和退单。而即将推出的升级版卖家保障政策将涵盖通过PayPal支付平台发起的邮件交易,从而更好的保护中国商户,使之更安心的进行跨境电子交易。

      • 人民币提款服务:通过合作伙伴连连支付的支持,PayPal将于近期推出可选择性人民币提款服务。原先,中国商户们须花约7天的时间提取账户中的美金,再通过其他方式换成人民币。有了此项服务,只需约2-3天的时间,商户就能将账户中的余额以人民币的形式提取出来,从而大大减轻商户的现金流压力,提升交易便捷性。此外,中国商户还可将所提款项直接转账至全国184家银行,随时随地,轻松进行跨境电子贸易。

      • 风险管控:PayPal拥有全球领先的风险管理系统,帮助卖家从交易开始之初便着手规避恶意欺诈风险。一旦买家提交购买订单,PayPal的欺诈检测模型便即时启动跟踪,对欺诈交易做出风险预警。一旦监测到可疑交易,PayPal将立即开展专业的人工核查,由世界一流的风险管理专家亲自核查,从而判定该笔交易是否存在欺诈嫌疑。

      • 国际物流运输:PayPal通过国内外领先物流伙伴合作,为中国商户提供更经济、快捷的物流选择及服务,使其能更便利、安全地将商品运输至海外买家手中;针对B2B2C市场,PayPal正联手TNT,推出针对B2B2C商户的专属速递物流解决方案,在服务、价格等方面均有专属的优惠。同时针对B2C商户,PayPal还拥有联手中国邮政推出的贝邮宝物流解决方案,有效地解决了邮政小包的可视化,并有机地与PayPal的卖家保障政策结合,帮助商户解决了货物的安全性及可追踪等问题。

      胡柏迪还表示:“PayPal 明白电子支付平台只是跨境电商市场的繁荣发展中的一环。我们一直在倾听中国商户的意见,持续创新,通过开发全方位解决方案为中国商户打造更健康的全球电商生态系统,从而帮助他们拓展业务。”

      来自深圳市亿通趋势科技有限公司和青岛阳光五月发制品有限公司的两位商户代表在活动现场表示,PayPal外贸电子商务大会是一个很好的平台,能让商户了解跨境电商领域的新趋势和新动向。他们均对PayPal针对跨境电商市场痛点而推出的创新解决方案表示兴奋,并期待通过这些新服务在全球范围内拓展业务。

      随着跨境电商的不断发展,外贸网站的地位也是与日俱增。360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

       

      ]]>
      Fri, 18 Sep 2015 07:17:11 +0000
      <![CDATA[跨境电商高峰论坛带来饕餮盛宴]]> https://www.360magento.com/blog/Cross-border-electricity-supplier-Forum/         日前,在“跨境电商高峰论坛”上,六位跨境电商企业的资深人士为现场观众带来一场饕餮盛宴,他们以“跨境电商的潜力和未来”为主题,深入解读“互联网+”剖析了目前跨境电商的现状和痛点,从物流、信息流、资金流三方面切入,畅谈跨境电商未来格局和潜力,集中展示外贸综合服务平台、跨境电商等新业态新模式。

           在这次论坛上,浙江点库电子商务有限公司销售总监康山以“跨境电商B2B2C物流解决方案”为主题,介绍了浙江点库一站式跨境电商物流服务体系及其全球分销平台。敦煌网副总裁王添天介以“开拓跨境电商的新蓝海”为主题,介绍了敦煌网作为全球领先的外贸交易平台的优势及其正在用自身优势开拓跨境电商新蓝海的方向。兰亭集势品牌事业部负责人吕然以“传统企业在跨境电商的品牌化之路”为主题,介绍了兰亭集势作为目前国内知名的外贸销售网站为中小型企业提供的跨境电商服务。四海商舟创始人周宁以“跨境电商的机遇和挑战”为主题,剖析了传统企业在跨境电商的品牌化之路。Wish招商经理Jerry以“移动跨境电商的未来”为主题,解读了Wish作为移动跨境电商平台的一匹黑马对移动端未来和发展潜力的看法,Paypal华东地区负责人温从镭以“助力中国企业 扬帆商业蓝海”为主题,分析了Paypal作为全球知名跨境电商支付公司为跨境电商提供的领先支付服务。

              360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Fri, 18 Sep 2015 02:40:52 +0000
      <![CDATA[Magento 发送邮件代码(使用数据库中模板)]]> https://www.360magento.com/blog/magento-send-email/ /* @var $translate Mage_Core_Model_Translate */ $translate = Mage::getSingleton('core/translate'); $translate->setTranslateInline(false); $storeId = Mage::app()->getStore()->getId(); $template ='1';

              这里,邮件模板的ID是由$template的值来定义的,可以到后台->System->Transactional Emails获取邮件模板ID,也可以用magento默认的值,如 'contacts_email_email_template'

       $recipient = array(  
                    'name'  => 'Alwayly',  
                   'email' => 'sales@360magento.com'  
               );         
               //$recipient 是接收者的名字和邮箱地址
      
               $sender  = array(  
                   'name'  => 'Alwayly',  
                   'email' => 'sales@360magento.com'  
               );
                //$sender 是发送者的名字和邮箱地址,
               
               magento默认用的这句 $sender=Mage::getStoreConfig('sales_email/order/identity', $storeId) ,使用magento后台配置的发送人
                 
               $mailTemplate = Mage::getModel('core/email_template')->load($template);  
      
               $mailTemplate->setDesignConfig(array('area'=>'frontend', 'store'=>$storeId))  
                   ->sendTransactional(
                       $template,  
                       $sender,  
                       $recipient['email'],  
                       $recipient['name'],  
                       array( // parameters to email  
                           'param1'=> 'abc',  
                           'param2'=> 'def',  
                           'param3'=> 'ghi'  
      

      这里是传进邮件模板里面的变量, 在模板里面用{{var param1 }}获取,如果传的是对象可以这样使用{{var object.getId()}} ) );

      $translate->setTranslateInline(true);

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 10:13:26 +0000
      <![CDATA[Magento Block应用原理分析以及magento调用其他phtml文件]]> https://www.360magento.com/blog/magento-transfer-block/ 如果你在本机的虚拟目录下建立了自己的magento项目,这里以项目名为magento为例,那么访问:

      http://localhost/magento/index.php/customer/account/create/ 将进入用户注册界面。

      下面就从URL尝试分析Magento调用该页面的过程

      1. 1. URL中的customer表明当前访问的模块是customer,自动定位到: app\code\core\Mage\Customer
      2. 2. URL中的account表明当前访问的控制器文件为AccountController.php app\code\core\Mage\Customer\controllers\AccountController.php
      3. 3.URL中的create表明当前访问的php方法是createAction(),该方法在文件 app\code\core\Mage\Customer\controllers\AccountController.php
      4. 4. createAction()装载目录\app\design\frontend\default\default\layout\下名字和模块名相同的 layout文件,名字为customer.xml。然后寻找名字为<customer_account_create>的标签

      Xml代码

      
      <customer_account_create translate="label">
                      <label>Customer Account Registration Form</label>
                      <!-- Mage_Customer -->
                      <remove name="right"/>
                      <remove name="left"/>
      
                      <reference name="root">
                          <action method="setTemplate"><template>page/1column.phtml</template></action>
                      </reference>
      
                      <reference name="content">
                          <block type="customer/form_register" name="customer_form_register" template="customer/form/register.phtml">
                              <block type="page/html_wrapper" name="customer.form.register.fields.before" as="form_fields_before" translate="label">
                                  <label>Form Fields Before</label>
                              </block>
                          </block>
                      </reference>
                  </customer_account_create>
      

      <reference name="root"> 用来说明你要使用的布局文件。

      <reference name="content">下的block就是你定义的block

      上面的block是默认定义,可以由customer/form_register推测出来,block类文件位置: app\code\core\Mage\Customer\Block\Form\Register.php

      template属性可找出出相应的模板文件为: app\design\frontend\default\default\template\customer\form\register.phtml

      通过这样的配置block和template就联系起来了,可以在template文件中使用$this来访问block类的方法。

      下面我们实现一个新的block应用

      1. 定义一个新的block文件:

      app\code\core\Mage\Customer\Block\Form\Register1.php

                      class Mage_Customer_Block_Form_Register1 extends Mage_Directory_Block_Data{  
                      public function getHello(){  
                        return "Hello Block";  
                     }  
               }
      

      2. 定义template文件:

      app\design\frontend\default\default\template\customer\form\register1.phtml

      Html代码:

      <?php echo $this->getHello(); ?>

      3. 修改customer.xml配置

      将Xml代码

      <block type="customer/form_register" name="customer_form_register" template="customer/form/register.phtml"/>

      修改为:

      <block type="customer/form_register1" name="customer_form_register1" template="customer/form/register1.phtml"/>

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 10:06:37 +0000
      <![CDATA[magento getResourceModel()函数分析详细讲解]]> https://www.360magento.com/blog/magento-getResourceModel/ getResourceModel()方法讲解

      $collection = Mage::getResourceModel( 'catalogsearch/fulltext_collection' );

      首先会找到app\code\core\Mage\CatalogSearch\etc\config.xml

      找到 <resourceModel>

      <resourceModel>catalogsearch_resource</resourceModel> 得出结果: 

      模型文件地址为:\app\code\core\Mage\CatalogSearch\Model\Resource

      加上参数,加载php文件地址为: \app\code\core\Mage\CatalogSearch\Model\Resource\Fulltext\Collection.php

      获取目录分类模板 Mage::getStoreConfig('catalog/frontend/grid_per_page_values'); 它找的是app\code\core\Mage\Catalog\etc\config.xml

      1. 找出<catalog>节点
      2. 找出<frontend>节点
      3. 找出节点grid_per_page_values里的值

      $helper = Mage::helper('catalog/category' );

      $_categories = $helper->getStoreCategories();获取顶级分类

      $categoryChildrens = $_category-> getChildren();获取子分类

      <?php echo $_category->getUrl(); ?>

      文件位置是:app\code\core\Mage\Catalog\Model\Category.php

      $tree = Mage::getResourceModel('catalog/category_tree');

      Mage_Catalog_Model_Resource_Category_Tree

      获取资源模型

      加载的文件是app\code\core\Mage\Catalog\Model\Resource\Category\Tree.php

      获取分类request_path SELECT `t1c_catalog_category_entity`.* FROM `t1c_catalog_category_entity` WHERE (`t1c_catalog_category_entity`.`entity_id` = '2')

      $this->getResource()

      //$this->getResource() = Mage_Catalog_Model_Resource_Category

      Mage_Catalog_Model_Category

      getChildrenCategories()找出子类方法

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 09:59:54 +0000
      <![CDATA[magento URL重写、Block重写、controller重写、model重写]]> https://www.360magento.com/blog/magento-rewrite/ 当我们给magento开发插件的时候,必然会碰到要改变系统的原来的行为的情况。而magento作为一种插件机制的灵活的系统,直接修改核心代码是极为不妥的方式。而有时magento的事件机制并不能解决问题的时候,重写原来的文件的需求就产生了。在此打算总结下magento中的各种重写。

      magento model的重写

      实现方法:新的model继承你要重写的model,然后配置文件配置model的rewrite。例子如下: class Zone_Test_Model_Quote extends Mage_Sales_Model_Quote { //这里写一些自定义的方法或者覆盖父类的一些方法来实现自己的逻辑 } <!--model rewrite xml配置--> <?xml version="1.0"?> <config> <!-- 这里省略其他配置... --> <global> <models> <sales> <rewrite> <quote>Zone_Test_Model_Quote</quote> </rewrite> </sales> </models> </global> </config>

      这样当我们用Mage::getModel(‘sales/quote’)的时候实例化的就不是Mage_Sales_Model_Quote这个类的对象,而是我们重写后的类的对象了。

      magento model重写的原理:

      追踪Mage::getModel()这静态方法会发现如下代码:

      //file: app/code/core/Mage/Core/Model/Config.php
      //function: getGroupedClassName
      if (empty($groupRootNode)) {
      $groupRootNode = 'global/'.$groupType.'s';</pre>
      }
      $classArr = explode('/', trim($classId));
      $group = $classArr[0];
      $class = !empty($classArr[1]) ? $classArr[1] : null;

      if (isset($this->_classNameCache[$groupRootNode][$group][$class])) {
      return $this->_classNameCache[$groupRootNode][$group][$class];
      }

      $config = $this->_xml->global->{$groupType.'s'}->{$group};

      // First - check maybe the entity class was rewritten
      $className = null;
      if (isset($config->rewrite->$class)) {
      $className = (string)$config->rewrite->$class;//这里就是重写的关键
      }

      通过上面的代码,我们不难看出,原理就是获取类名的时候先查找是否有rewrite的节点,有就直接用rewrite的类名去实例化对象。

      magento Block的重写

      关于Block的重写因为block的实例化和model的实例化共用的一段代码,所以方法和配置也差不多,唯一的不同是block重写的配置节点为global/blocks,而model的是global/models。

      magento controller的重写

      实现方法:和model、block的重写方法差不多,新建自己的controller,然后配置下配置下模块的配置文件,让系统实例化 controller的时候能找到对应的类名。我们举个例子,重写checkout模块的cart 这个controller。代码如下:

       
      //首先新建自己的controller在自己的模块controllers目录里面
      class Zone_Test_CartController extends Mage_Checkout_CartController
      {
      //这里新加自己的函数或者重写覆盖父类的同名函数
      }
      
      
      <!--然后就是配置文件:-->
      <?xml version="1.0"?>
      <config>
      <!-- 这里省略其他配置... -->
      <frontend>
      <routers>
      <checkout>
      <args>
      <modules>
      <Zone_Test before="Mage_Checkout">Zone_Test</Zone_Test>
      </modules>
      </args>
      </checkout>
      </routers>
      </frontend>
      </config>

      这样配置好后,当我们在浏览器上输入http://youhost/checkout/cart的时候实际上执行的是我们自己的模块里面的Zone_Test_CartController这里类的对象的indexAction方法。

      magento 重写实现原理:

      magento在路由过程中会通过url获取到frontName为“checkout”和controller为“cart”,然后通过路由器的 getModuleByFrontName方法获取到一个数组,这数组就是我们配置的modules,而且是排序过的,排序按配置节点的before或者 after来排序的。我们这个例子就array(‘Zonet_Test’, ‘Mage_Checkout’),然后遍历这个数组通过数组里面的值和cart去取到对应的controller类 Zone_Test_CartController,实例化然后执行对应的action方法。相关代码如下:

      //file:app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
      //function:match

      public function match(Zend_Controller_Request_Http $request)
      {
      ...
      /**
      * Searching router args by module name from route using it as key
      */
      $modules = $this->getModuleByFrontName($module);//获取真实模块的数组,也就是合并模块路由配置里面的module和modules。
      ...
      /**
      * Going through modules to find appropriate controller
      */
      $found = false;
      foreach ($modules as $realModule) {//这个循环里按配置的顺序去拼接controller类
      $request->setRouteName($this->getRouteByFrontName($module));

      // get controller name
      if ($request->getControllerName()) {
      $controller = $request->getControllerName();
      } else {
      if (!empty($p[1])) {
      $controller = $p[1];
      } else {
      $controller = $front->getDefault('controller');
      $request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,ltrim($request->getOriginalPathInfo(), '/'));
      }
      }

      // get action name
      if (empty($action)) {
      if ($request->getActionName()) {
      $action = $request->getActionName();
      } else {
      $action = !empty($p[2]) ? $p[2] : $front->getDefault('action');
      }
      }

      //checking if this place should be secure
      $this->_checkShouldBeSecure($request, '/'.$module.'/'.$controller.'/'.$action);

      $controllerClassName = $this->_validateControllerClassName($realModule, $controller);
      if (!$controllerClassName) {
      continue;
      }

      // instantiate controller class
      $controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $front->getResponse());

      if (!$controllerInstance->hasAction($action)) {
      continue;
      }

      $found = true;
      break;
      }

      }

      magento 抽象类的rewrite

      对于抽象类的重写和model的重写有点不一样,因为抽象类是直接用来继承的,并没用到方法工厂,所以只能用其他方式去重写了。方法就是复制同样的文件结构到local代码池里面,然后对整个类复制过去,新增或者修改其中的方法来实现重写。原理就是magento的自动加载优先加载local的代码。代码如下:

      
      //file:app/Mage.php
      /**
      * Set include path
      */
      $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'local';
      $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'community';
      $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core';
      $paths[] = BP . DS . 'lib';
      
      $appPath = implode(PS, $paths);
      set_include_path($appPath . PS . Mage::registry('original_include_path'));
      include_once "Mage/Core/functions.php";
      include_once "Varien/Autoload.php";
      

      magento url rewrite

      这里不讨论服务器上面实现的urlrewrite。magento的url rewrite有两种方法:1、xml配置。2、系统自带的产品和目录的url rewrite,这里后台也可以自定义url rewrite。关于后台的url rewrite这里不多说,不清楚的自行查看magento的使用手册。这里主要讲下xml配置及其实现原理,还有就是简答讲下系统自带的基于数据库的 rewrite的原理。

      
      基于xml配置的url rewrite的例子:
      <!--模块配置文件:config.xml-->
      <?xml version="1.0" encoding="UTF-8"?>
      <config>
      <!-- 省略的其他配置...-->
      <global>
      <!-- 省略的其他配置... -->
      <rewrite>
      <myrewrite>
      <from> <![CDATA[#/shopby/([\w+\+]+).html#]]></from>
      <to><![CDATA[/catalogsearch/result/index/q/$1]]></to>
      <complete/>
      </myrewrite>
      </rewrite>
      </global>
      </config>

      这个例子就实现了/shopby/querytext.html到/catalogsearch/result/index/q/querytext的rewrite。

      我们看看magento是怎么实现这个的。这个rewrite是发生在magento的前端控制器分发请求的时候,顺序在基于数据库的rewrite之后。原理很简单,就是查找各个模块配置文件里面global/rewrite节点取出rewrite配置,遍历这些配置通过正则替换把符合条件的from 替换成to,然后改变request对象的pathinfo。具体实现代码如下:

       
      public function rewrite()
      {
      $request = $this->getRequest();
      $config = Mage::getConfig()->getNode('global/rewrite');
      if (!$config) {
      return;
      }
      
      foreach ($config->children() as $rewrite) {
      $from = (string)$rewrite->from;
      $to = (string)$rewrite->to;
      if (empty($from) || empty($to)) {
      continue;
      }
      
      //这里实现了路由名到前端路由器的替换,把{routeName}替换成对应的frontName,不过一般来说很多模块的routeName和frontName配置成一样了,这个特性使用的不多。
      $from = $this->_processRewriteUrl($from);
      $to = $this->_processRewriteUrl($to);
      
      //这里是替换的核心所在,通过这句代码也很清楚的知道from 和to该填什么内容。
      
      $pathInfo = preg_replace($from, $to, $request->getPathInfo());
      
      if (isset($rewrite->complete)) {
      $request->setPathInfo($pathInfo);
      } else {
      $request->rewritePathInfo($pathInfo);
      }
      }
      }
      

      关于系统自带的关于产品和目录的url rewrite,前端控制器里面只调用了一句代码: Mage::getModel(‘core/url_rewrite’)->rewrite(),这是调用了核心模块的url rewrite model来处理的。这里面通过数据根据请求路径查找到目标路径,然后看数据库里面是配置的301还是302做相应的类型的跳转,这是通过php的 header函数实现的。剩下的类型就直接改变request 对象的pathinfo。这块magento有一个做的很好的地方,就是对于同一个产品或者目录url rewrite修改过后,原来的记录并不会删除,而是和新的rewrite相关联,这样老的url进来也能跳转的新的url上去,有利于seo。这块具体代码就不分析了,有空专门写个文章。有兴趣的自行翻看代码。

      magento config path rewrite

      magento的后台system配置,读取的时候一般按system.xml的节点路径来的。但是有的时候当我们不想使用这个路径的时候,配置时可以指定config_path的路径。这个常用于支付插件。因为获取支付类型的时候是通过固定的一个path取的,而我们模块自己的系统配置会用自己的路径,这时候config path就派上用场了。看下面的例子:

       <!--//file:system.xml 这是moneybookers模块的system.xml文件的一个片段-->
              <active translate="label">
                 <label>Enabled</label>
                 <frontend_type>select</frontend_type>
                 <config_path>payment/moneybookers_gir/active</config_path>//这里重写了config path
                 <source_model>adminhtml/system_config_source_yesno</source_model>
                 <sort_order>1</sort_order>
                 <show_in_default>1</show_in_default>
                 <show_in_website>1</show_in_website>
                 <show_in_store>1</show_in_store>
              </active>

      实现原理就更简单了,保存store config的时候,检查下有没有confg_path有就按这个path来保存到数据库。代码如下:

      
      //file: app/code/core/Mage/Adminhtml/Model/Config/Data.php
      //functon: save
      
      /**
      * Look for custom defined field path
      */
      if (is_object($fieldConfig)) {
      $configPath = (string)$fieldConfig->config_path;
      if (!empty($configPath) && strrpos($configPath, '/') > 0) {//这里开始对自定义的path进行处理
      // Extend old data with specified section group
      $groupPath = substr($configPath, 0, strrpos($configPath, '/'));
      if (!isset($oldConfigAdditionalGroups[$groupPath])) {
      $oldConfig = $this->extendConfig($groupPath, true, $oldConfig);
      $oldConfigAdditionalGroups[$groupPath] = true;
      }
      $path = $configPath;
      }
      }
      
      $inherit = !empty($fieldData['inherit']);
      
      $dataObject->setPath($path)
      ->setValue($fieldData['value']);
      

      magento template rewrite

      当我们写插件的时候想改变原有系统的某个template的时候比如产品详细页面的模板,因为是插件我们没办法控制它的theme只能通过xml配置来重写template了,原理也很容易,就是利用block的配置的action 节点,通过action节点来设置template。例子如下:

      
      <!-- file: mylayout.xml --->
      <layout version="0.1.0">
      <catalog_product_view>
      <reference name="product.info">
      <action method="setTemplate"><template>test/product/myselfview.phtml</template>
      </action>
      </reference>
      </catalog_product_view>
      </layout>

      这样通过插件的layout配置就可以改变产品详细页面的template为自己插件的模板。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 09:51:29 +0000
      <![CDATA[magento newsletter发送不成功讲解及代码分析]]> https://www.360magento.com/blog/magento-fail-to-send-newsletter/ 今天有个同事问我,昨天在后台建了一个newsletter的队列为什么到今天队列状态还是为未发送。询问了下cronjob的运行情况,发现 magento的cronjob是正常运行的,而邮件配置也是对的,其他邮件都能正常发送。百思不得其解,于是只好拿出杀手锏,翻源码追踪整个发送过程。一追踪下来马上发现了这根本就不是个问题,问题在我们对newsletter的发送不熟悉,对什么时候修改这个状态理解错误。下面让我们系统的学习下 magento的newsletter。

      newsletter的订阅

      magento的前台页面一般都会有一个小的表单用来输入邮箱号码,客户提交就可以订阅相关产品信息了。网站后台建立邮件队列,就可以批量的对订阅者发送邮件来进行营销。后台还可以开启邮件确认的功能,开启邮件确认功能后,用户提交订阅newsletter的表单时先把订阅状态设置为2,即未确认状态,然后生成一个随机字符串保存并发送确认邮件,邮件里面的链接带有生成的随机字符串。用户点链接确认的时候就把请求传入的字符串和保存在数据库的字符串对比,如果一致就把状态改成1,即订阅状态。newsletter订阅相关数据保存到newsletter_subscriber这个表。

      newsletter邮件模板的创建

      后台newsletter => newsletter templates =>add new template就可以创建newsletter的邮件模板了,和其他邮件模板差不多的写法,区别是这只有一个变量就是subscriber对象,而且不能像订单之类的邮件模板一样可以选文件模板来修改,不过还好有些默认的代码。照着改改就好了。这个邮件模板的数据保存到数据库表 newsletter_template中。

      newsletter队列的创建

      当你创建好newsletter模板的时候会回到newsletter模板列表页面,每行模板右侧都有一个action列,下拉选择Queue Newsletter就会跳到创建页面。这个页面和newsletter模板的表单差不多,就多了一个队列开始执行的时间以及选择对应店铺的地方。填好点保存就创建了一个newsletter队列。那么创建一个队列的时候都干了些什么呢?首先,肯定是把我们填写的信息都保存到数据库中,这里是保存到 newsletter_queue这个表中。然后,它还做了一个事情就是保存队列和店铺的关系,队列和店铺关联的信息保存在表 newsletter_queue_store_link。我们看看保存queue店铺关系相关的代码。

      app/code/core/Mage/Adminhtml/controllers/Newsletter/QueueController.php文件saveAction 方法中

             
              $queue->setStores($this->getRequest()->getParam('stores', array()))//这里保存了店铺信息
              ->setNewsletterSubject($this->getRequest()->getParam('subject'))
              ->setNewsletterSenderName($this->getRequest()->getParam('sender_name'))
              ->setNewsletterSenderEmail($this->getRequest()->getParam('sender_email'))
              ->setNewsletterText($this->getRequest()->getParam('text'))
              ->setNewsletterStyles($this->getRequest()->getParam('styles'));
               
              //app/code/core/Mage/Newsletter/Model/Queue.php
               
              public function setStores(array $storesIds)
               {
               $this->setSaveStoresFlag(true);//设置保存的标志
               $this->_stores = $storesIds;
               return $this;
               }
               
              //app/code/core/Mage/Newsletter/Model/Resource/Queue.php
               
              //queue model保存的之后会执行该方法
              protected function _afterSave(Mage_Core_Model_Abstract $queue)
               {
               if ($queue->getSaveStoresFlag()) {
               $this->setStores($queue);
               }
               return $this;
               }
               
              public function setStores(Mage_Newsletter_Model_Queue $queue)
               {
              //先把对应的queue store关系在表里删除掉
               $adapter = $this->_getWriteAdapter();
               $adapter->delete(
               $this->getTable('newsletter/queue_store_link'),
               array('queue_id = ?' => $queue->getId())
               );
               
              $stores = $queue->getStores();
               if (!is_array($stores)) {
               $stores = array();
               }
               
              foreach ($stores as $storeId) {
               $data = array();
               $data['store_id'] = $storeId;
               $data['queue_id'] = $queue->getId();
               
              //插入queue和store关系到表newsletter_queue_store_link中
              $adapter->insert($this->getTable('newsletter/queue_store_link'), $data);
               }
               $this->removeSubscribersFromQueue($queue);
               
              if (count($stores) == 0) {
               return $this;
               }
               
              //取所有订阅者的信息
              $subscribers = Mage::getResourceSingleton('newsletter/subscriber_collection')
               ->addFieldToFilter('store_id', array('in'=>$stores))
               ->useOnlySubscribed()
               ->load();
               
              $subscriberIds = array();
               
              foreach ($subscribers as $subscriber) {
               $subscriberIds[] = $subscriber->getId();
               }
               
              if (count($subscriberIds) > 0) {
              //把队列和订阅者的关系插入到newsletter_queue_link表中
              $this->addSubscribersToQueue($queue, $subscriberIds);
               }
              return $this;
               }
      

      newsletter邮件的发送

      队列创建后并不会马上就会发送邮件。newsletter的邮件发送是通过magento的cronjob机制来执行的。模块配置里面配置好执行周期以及对应的执行方法,并服务器里面定时执行网站跟目录的cron.php或者cron.sh邮件才会发送。配置如下:

      
            <!--  newsletter 模块配置文件config.xml -->
      <crontab>
      <jobs>
      <newsletter_send_all>
      <schedule>
      <cron_expr>*/5 * * * *</cron_expr>
      </schedule>
      <run>
      <model>newsletter/observer::scheduledSend</model>
      </run>
      </newsletter_send_all>
      </jobs>
      </crontab>

      */5 * * * *这个和linux下的crontab一样,表示每5分钟执行一次。这里是执行Mage::getModel(‘newsletter/observer’)->scheduledSend();我们看看这个方法:

              
      //app/code/core/Mage/Newsletter/Model/Observer.php
              public function scheduledSend($schedule)
               {
               $countOfQueue = 3;//一次只处理三个队列
               $countOfSubscritions = 20;//一个队列只发其中的20封邮件
               
              $collection = Mage::getModel('newsletter/queue')->getCollection()
               ->setPageSize($countOfQueue)
               ->setCurPage(1)
               ->addOnlyForSendingFilter()//只对队列里面没发过邮件的订阅者发邮件,判断是否发过是通过表newsletter_queue_link表中letter_sent_at这个字段是否为空来判断的
               ->load();
               
              //对每一个队列model执行sendPerSubcritber方法
              $collection->walk('sendPerSubscriber', array($countOfSubscritions));
               }
      

      发邮件的代码和magento其他模块发邮件没啥区别,就是取出我们设置好的邮件模板替换变量然后调用邮件发送类发送。

      但是这里有个需要注意的地方,那就是 一次只是发20封邮件,当队列对应的订阅者都发完了之后才会修改队列状态为已发送。

      
              //app/code/core/Mage/Newsletter/Model/Queue.php
               
              public function sendPerSubscriber($count=20, array $additionalVariables=array())
               {
               
              // .....
               
              if ($this->getSubscribersCollection()->getSize() == 0) {
               $this->_finishQueue();
               return $this;
               }
               
              //.....
               
              //发送完毕,修改成已经发送状态
              if(count($collection->getItems()) < $count-1 || count($collection->getItems()) == 0) {
               $this->_finishQueue();
               }      
              }
               
              protected function _finishQueue()
               {
               $this->setQueueFinishAt(Mage::getSingleton('core/date')->gmtDate());
               $this->setQueueStatus(self::STATUS_SENT);
               $this->save();      
              return $this;
               }
      

      现在回到今天同事问的那个问题。队列是昨天创建的,而我们的订阅数有很多,假设就一万个吧,newsletter每五分钟才发20封邮件,要发完一万封就需要 2500分钟,差不多42个小时。邮件还没发完嘛,状态当然不会变成已经发送了。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 09:47:13 +0000
      <![CDATA[magento 事务处理使用方法]]> https://www.360magento.com/blog/magento-transaction-processing/ Mangeto中执行某个功能时,如update、insert、delete,magento的model会自动对事务进行处理。这些写操作都集中到 model的save方法或者delete方法来处理,执行时候会调用resource model的beginTransaction方法来开启事务,调用resource model的commit方法来提交事务,调用resource model的rollBack方法来回滚事务。save方法代码如下:

      
              public function save()
               {
               /**
               * Direct deleted items to delete method
               */
               if ($this->isDeleted()) {
               return $this->delete();
               }
               if (!$this->_hasModelChanged()) {
               return $this;
               }
               $this->_getResource()->beginTransaction();//开启事务
               $dataCommited = false;
               try {
               $this->_beforeSave();
               if ($this->_dataSaveAllowed) {
               $this->_getResource()->save($this);
               $this->_afterSave();
               }
               $this->_getResource()->addCommitCallback(array($this, 'afterCommitCallback'))
               ->commit();//添加提交后的回调函数
               $this->_hasDataChanges = false;
               $dataCommited = true;
               } catch (Exception $e) {
               $this->_getResource()->rollBack();//异常时事务回滚
               $this->_hasDataChanges = true;
               throw $e;
               }
               if ($dataCommited) {
               $this->_afterSaveCommit();
               }
               return $this;
               }
      

      delete方法和save类似,这里就不贴代码出来分析了。

      多个model的事务处理

      单个model的事务处理很简单,magento的model层直接就处理了,不需要额外的代码。那么当我们的业务同时涉及到多个model,并且必须是当成一个事务来处理的时候,该怎么处理呢?不用担心,像magento这么优秀的系统不可能不会考虑到这些情况的。于是类 Mage_Core_Model_Resource_Transaction派上用场了。一个典型的多model事务处理如下:

              
      $transaction = Mage::getModel('core/resource_transaction');
              $transaction->addObject($model1);
              $transaction->addObject($model2);
              $transaction->addObject($model3);
              //...
               
              try {
               $transaction->save();
              //或者进行删除操作$transaction->delete();
               } catch (Exception $e) {
              //异常处理
              }
      

      那么当我们通过addObject把相关的model都添加到事务处理器 Mage_Core_Model_Resource_Transaction里面并执行save或者delete的时候,做了什么呢?我们以save为例子进行深入。

              
      public function save()
               {
               $this->_startTransaction();//开启事务
               $error = false;
               
              try {
               foreach ($this->_objects as $object) {
               $object->save();//遍历添加进来的oject并执行其save方法
               }
               } catch (Exception $e) {
               $error = $e;
               }
               
              if ($error === false) {
               try {
               $this->_runCallbacks();//执行回调函数
               } catch (Exception $e) {
               $error = $e;
               }
               }
               
              if ($error) {
               $this->_rollbackTransaction();//异常,回滚事务
               throw $error;
               } else {
               $this->_commitTransaction();
               }       
              return $this;
               }
               
              protected function _startTransaction()
               {
              //遍历相关对象执行对象的resource model的beginTransaction方法开启事务
               foreach ($this->_objects as $object) {
               $object->getResource()->beginTransaction();
               }
               return $this;
               }
               
              protected function _commitTransaction()       
              {
              //遍历相关对象执行对象的resource model的commit方法提交事务
               foreach ($this->_objects as $object) {
               $object->getResource()->commit();
               }
               return $this;
               }
               
              protected function _rollbackTransaction()
               {
              //遍历相关对象执行对象的resource model的rollBack方法提交事务
               foreach ($this->_objects as $object) {
               $object->getResource()->rollBack();
               }
               return $this;
               }
      

      代码很容易理解和单个model的save方法流程是一致的,只是开启事务、提交事务或者回滚事务的时候是遍历执行各个model的相关方法。

      那么这个时候我们就会有这样的疑惑:开启事务的方法执行了好几遍,这样会不会出问题呢?如果是真的多次执行数据库对事务相关的sql的话,那么肯定是会有问题的。 magento很好的处理了这个问题。就是resouce model层对事务有了一个层级的概念。多次提交事务,只有第一次才是真的提交事务,后面的多次只是事务的level计数器加一,同样的对于commit 和rollback只有计数器为0的时候才真正执行相关的操作,其他时候都是计数器减一,这样就避免了我们前面提出的那个问题的出现了。看相关代码:

      
              //file:lib/Varien/Db/Adapter/Pdo/Mysql.php
              public function beginTransaction()
               {
               if ($this->_transactionLevel === 0) {
               $this->_debugTimer();
               parent::beginTransaction();
               $this->_debugStat(self::DEBUG_TRANSACTION, 'BEGIN');
               }
               ++$this->_transactionLevel;
               return $this;
               }
               
              public function commit()
               {
               if ($this->_transactionLevel === 1) {
               $this->_debugTimer();
               parent::commit();
               $this->_debugStat(self::DEBUG_TRANSACTION, 'COMMIT');
               }
               --$this->_transactionLevel;
               return $this;
              }
               
              public function rollback()
               {
               if ($this->_transactionLevel === 1) {
               $this->_debugTimer();
               parent::rollback();
               $this->_debugStat(self::DEBUG_TRANSACTION, 'ROLLBACK');
               }
               --$this->_transactionLevel;
               return $this;
               }
      

      最后提醒一点,对于mysql来说,只有innodb存储引擎才有事务功能。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 09:43:49 +0000
      <![CDATA[16条必须的magento SEO优化设置]]> https://www.360magento.com/blog/16-magento-seo-configuration/ 16条必须的magento SEO优化设置
      1. 可以用文章,blog页面做长尾关键词
      2. 在每个页面做一个文章框,随即显示文章,这样可以更新此页面。
      3. search页面在robots.txt设置不让抓取
      4. URL重写开启,使用绝对地址(这个应该没有问题),URL标准化,避免多个URL指向一个页面,造成权重的分散
      5. 404页面的制作
      6. 放置统计代码,用google的统计
      7. robots.txt设置成不可写吧。
      8. local.xml设置成通过url不可访问
      9. 分类页面的产品名称,magento默认模板用的是H2,要改掉
      10. 避免一个页面出现多个h1情况。如果没有h1标签可以写一个,然后隐藏掉!
      11. 每一个图片的alt要写上。
      12. 标签的title也写上,尽量
      13. 在后台为首页,产品分类页面,写入<h1>标签的内容,作为内容标题!
      14. css,js代码尽量写在对用的文件里面,html页面尽量代码简洁,去掉之间大量空格,和繁琐的注释
      15. 对于不希望google抓取的内容,和外部信息设置成nofollow,从而避免权重的流失。
      16. 开启缓存,编译,js,css合并,提速。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 08:18:24 +0000
      <![CDATA[谈magento对谷歌搜索引擎的友好]]> https://www.360magento.com/blog/magento-google-seo/ if there is a word can describe the relation of magento & Google Search Engine , it must be friend!

      如果能有词形容magento和谷歌搜索引擎的关系,那么肯定是“朋友”!

      magento是目前国外使用最多的开源网店系统,而且它的使用领域已经逾越了商城,等效于博客或者CMS了。而作用一个英文站点开发人员,我们认为之所以那么多站长朋友使用magento进行网站建设,其最大的原因或者正是magento对谷歌搜索引擎高度友好。

      为什么说magento对Google友好呢?

      magento几乎拥有自定义性

      无论是哪个类模型,你都可以在magento后台命名它的title,keywords以及description甚至是url以及meta。这个功能让网站在后期的推广能够获得不错的表现,而且这也是大多seo选择网站开发系统的标准之一。

      magento卓越的性能表现

      magento能够快速处理任何自身的进程,高效地反馈网站给访客。而且经过官方作过压力测试,完全能够胜任大数据处理,并不会产生冗余的垃圾文件,所以Google机器人非常愿意爬去这些页面。

      选择网站开发的系统,我们的最重的应该就是以上两点,而magento都拥有了。用SEO经典的一句话说就是“爬虫其实就是普通用户”,所以受大众欢迎的,同样也会受搜索引擎欢迎。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 08:06:50 +0000
      <![CDATA[了解跨境电商的市场,让您更好的找到定位]]> https://www.360magento.com/blog/Cross-border-e-commerce/ 电子商务行业中,有不少的人在讲,现在电商越来越难做了。没错,大平台的电商已经很成熟,现在走出这一困局才是明智之举,而近两年来最为火爆的是:跨境电商,农村电商,社交电商。 这些电商新形态已在不断爆发中,今天为您分享一下跨境电商中,值得开拓也是必须了解的跨境电商市场,这些是跨境电商中的进口大国:

      跨境电商人必须了解的五个国家

      1. 韩国

        韩国的网络速度全球最快,也难怪它是全球第七大、亚太地区第三大电商零售市场。预计韩国2015年总零售额达367.6亿美元,其中网络零售额占9.8%。

      2. 澳大利亚

        澳大利亚2014年电商销售额增长了17.3%,这也表明澳大利亚人是网购的忠实粉丝。数据显示,大约79.4%的互联网用户通过电子渠道购物。尽管人口数量较少,但是澳大利亚仍然充满了机遇。

      3. 法国

        法国2014年电商销售额增长了11%,电商企业应该考虑法国这个市场。作为世界上第六大、欧洲第三大的电商市场,法国有很大的发展机会。预计法国2015年的电商市场规模将增长10%,达624亿欧元。

      4. 英国

        在欧洲地区,英国人最常上网购物,这也让英国成为继美国、中国之后的第三大电商市场。英国消费者平均每年的网购开支为1174英镑,网络零售额也将持续增长,英国为电商企业提供了很多发展空间。

      5. 俄罗斯

        俄罗斯位于欧亚大陆北部,地跨欧亚两大洲,国土面积为1707.54万平方公里,是世界上面积最大的国家。人口数量1.43亿(2014年),电子商务发展迅速,但由于本土电商平台不够影响力,并且俄罗斯人更喜欢在阿里平台上购买,所以在俄罗斯的购物平台排名中,速卖通排在第一位,而且有不少俄罗斯人还会在淘宝上购物!

      看了以上的国家的相关数据和基本的电商情况后,跨境电商的小伙伴,你们有什么想法的呢?!

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Thu, 17 Sep 2015 07:44:47 +0000
      <![CDATA[magento性能优化]]> https://www.360magento.com/blog/magento-optimization/ magento模版功能强大,已被大众所熟知,但也有不少朋友反映,magento网站的速度偏慢。在参考了一些资料后,对magento性能提升做一下小结。希望对各位读者有所帮助。

      1. 压缩js,css代码,如果有必要把所有的css,js分别综合到一个文件中,并压缩,缓存
      2. 清除magento模板中不必要的注释,为所使用到的图片瘦身
      3. 优化magento代码,这个步骤工作量大,但可能是效果显著的步骤,不过前提是你非常熟悉magento,彻底删除不用的模块,关闭没用的block, 清除无效,无用的xml(解析xml非常昂贵的),在一个页面中尽量不要大量调用magento的image resize功能,非常消耗内存,除非你自己优化代码。
      4. mysql配置优化,充分发挥你的硬件资源,下面的数值要根据你的配置调整 key_buffer_size = 512M max_allowed_packet = 64M table_cache = 512 sort_buffer_size = 4M net_buffer_length = 8K read_buffer_size = 4M read_rnd_buffer_size = 2M myisam_sort_buffer_size = 64M tmp_table_size = 128M query_cache_size = 96M query_cache_type = 1 thread_cache_size = 8 max_connections = 400 wait_timeout = 300
      5. 将magento的var目录挂载到内存中,加快读取速度,如mount -t tmpfs -o size=100M,mode=0777 tmpfs var
      6. 安装php加速器,如APC,XCACHE,eAccelerator,安装方法参考相关的网站。然而归于根本,最大的优化来自于对模板,对代码,对block的优化。

      在Magento的优化中, Mysql的优化是很重要的,在Magento的官方网给出了有关Mysql的优化, 官方网并没有要我们把Mysql的存储引擎改为innodb, 但我觉的得这是很有必要的,当改成innodb后,还得把Mysql的配置文件修改修改下, 有时根据官方的文档来并不能成功, 这时就要看你的环境而定了, 下面给出我所配置的mysql文件给大家参考:

        [mysqld]
      • datadir=/var/lib/mysql
      • socket=/var/lib/mysql/mysql.sock
      • user=mysql
      • # Default to using old password format for compatibility with mysql 3.x
      • # clients (those using the mysqlclient10 compatibility package).
      • old_passwords=1
      • default-character-set=utf8
      • #init_connect='SET NAMES utf8'
      • default-storage_engine = innodb
      • # To allow mysqld to connect to a MySQL Cluster management daemon, uncomment
      • # these lines and adjust the connectstring as needed.
      • #ndbcluster
      • #ndb-connectstring="nodeid=4;host=localhost:1186"

      [client]

      • #default-character-set=utf8

      [mysqld_safe]

      • log-error=/var/log/mysqld.log

      [Magento]

      • max_connections = 1000
      • max_connect_error = 10
      • table_cache = 1024
      • max_allowed_packet = 16M
      • max_heap_table_size = 64M
      • sort_buffer_size = 8M
      • join_buffer_size = 8M
      • thread_cache_size = 8
      • thread_concurrency = 8
      • query_cache_size = 64M
      • query_cache_limit = 2M
      • tmp_tables_size = 64M
      • key_buffer_size = 32M
      • read_buffer_size = 2M
      • read_rnd_buffer_size = 16M
      • bulk_insert_buffer_size = 64M
      • myisam_sort_buffer_size = 128M
      • myisam_max_sort_file_size = 10G
      • myisam_max_extra_sort_file_size=10G
      • myisam_repair_threads = 1
      • myisam_recover
      • innodb_additional_mem_pool_size = 16M
      • innodb_log_buffer_size = 8M
      • innodb_log_file_size = 512M
      • innodb_log_files_in_group = 2
      • innodb_buffer_pool_size = 3G
      • innodb_data_file_path = ibdata1:3G;ibdata2:1G:autoextend
      • innodb_autoextend_increment=512

      这里主要讲的是自己编译的Apache, 而如果是系统自带的话, Apache所需的模块, 系统会自动加载。

      • #vi httpd.conf
      • ServerTokens OS
      • ServerRoot "/etc/httpd"
      • PidFile run /httpd.pid
      • Timeout 120
      • KeepAlive off
      • MaxkeepAliveRequests 100
      • KeepAliveTimeout 15
      • StartServers 100
      • MinSpareServers 100
      • MaxSpareServers 150
      • ServerLimit 256
      • MaxClient 256
      • MaxRequestsPerChild 40000
      • Listen *:80

      在这里还要一些必须的Apache模块

        1. mod_authz_host.so
        2. mod_expires.so
        3. mod_deflate.so
        4. mod_mime.so
        5. mod_dir.so
        6. mod_rewrite.so 这个模块很重要, 当设置Magento地址重写时,要用到
        7. mod_log_config.so
        8. libphp5.so 你有可能用的是php4, 那就得改成libphp4.so

      注意:

      在安装好Apache后, 我们还能让Apache识别以php为后缀的文件

      AddType application/x-httpd-php .php .phtml

      好了, 到这就讲完了, 这章其实对Magento的优化不大, 但有些模块又不能少, 少了, Magento后台可能出问题

      当我们安装好Magento时, 为了加快Magento的速度,我们一般还要做一些对于Magento服务的优化, 来提高Magento被访问的速度。 一般我们会从三个角度去考虑Magento的优化, 如: 安装Magento的系统; Magento模板中的代码; Magento所用到的数据库。 在这我们主要讲的是Magento系统的优化

      Magento是在PHP环境下开发的, 所以优化PHP对Magento有着不小的影响,下面是Magento标准的PHP配置。

      对于Magento所需的扩展, 只开启所需的就可以了

      # Required extensions

      • extension=bcmath.so
      • extension=curl.so
      • extension=dom.so
      • extension=gd.so
      • extension=mcrypt.so
      • extension=memcache.so
      • extension=mhash.so
      • extension=pdo.so
      • extension=pdo_mysql.so
      • extension=mysql.so
      • extension=xmlwriter.so

      下面的一些扩展并不需要开启, 我们可以把它们关闭

      # Not  needed extensions from default setup

      • ;;extension=dbase.so
      • ;;extension=json.so
      • >
      • ;;extension=mysqli.so
      • ;;extension=pdo_sqlite.so
      • ;;extension=sqlite.so
      • ;;extension=wddx.so
      • ;;extension=smlreader.so
      • ;;extension=xsl.so
      • ;;extesnion=zip.so

      事无绝对, 当你的系统环境需要某个扩展时, 可以按照需要开启

      下面所要讲的, 也是PHP中优化的重点, 将会讲到二种方法,二选一就行了, 切忌, 不能同时应用二种方案

      一,安装APC扩展, APC, 用来优化PHP本身, 提高PHP的运行速度

      # APC configuration apecifics if it is used

      extension=apc.so

      apc.shm_size=256

      apc.num_files_hint=10000

      apc.user_entries_hint=10000

      apc.max_file_size=5M

      二,安装eaccelerator加速器,功能跟APC类似, 在这就不多说了。

      安装好eaccelerator后,将会产生eaccelerator模块

      zend_extension="/usr/lib64/php/modules/eaccelerator.so"

      eaccelerator.shm_size = "256"

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 16 Sep 2015 08:45:12 +0000
      <![CDATA[Magento建站知识]]> https://www.360magento.com/blog/magento/ 外贸B2C商城网店--Magento建站

      Magento是一套专业开源的PHP电子商务系统。Magento设计得非常灵活,具有模块化架构体系和丰富的功能。

      特点

      Magento设计得非常灵活,具有模块化架构体系和丰富的功能。易于与第三方应用系统无缝集成。

      设计

      在设计上,包含相当全面,以模块化架构体系,让应用组合变得相当灵活,功能也相当丰富。

      应用

      其面向企业级应用,可处理更方面的需求,以及建设一个多种用途和适用面的电子商务网站。 包括购物、航运、产品评论等等,充分利用开源的特性,提供代码库的开发,非常规范的标准,易于与第三方应用系统无缝集成。 为了打开盈利途径,Magento 同时具备收费的企业版本,积极谋求合作和第三方整合的工具,比如电子支付平台等。

      Magento开源网店系统的特点主要分以下几大类

      1. 网站管理
      2. 促销和工具
      3. 国际化支持
      4. SEO搜索引擎优化
      5. 结账方式
      6. 运输快递
      7. 支付方式
      8. 客户服务
      9. 用户帐户
      10. 目录管理
      11. 目录浏览
      12. 产品展示
      13. 分析和报表
      14. 自动被Google收录
      15. 一后台多网店系统

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 16 Sep 2015 04:32:19 +0000
      <![CDATA[轻松解决你的Magento毛病:整理最全的 Magento 常用SQL命令]]> https://www.360magento.com/blog/magento-sql/ Magento SQL命令可以加快解决你遇到的问题,不同版本,数据库可能会有所不同,所以SQL命令可能也会有所变化,在用SQL命令的时候一定要记得备份!!

      1. 批量调整所有产品的价格 
      UPDATE `catalog_product_entity_decimal` SET value=round(value*1.45) WHERE attribute_id=99;
      执行完后,需要到缓存管理里刷新:Layered Navigation Indices ,即可同步数据库里的关联表。

      2. 批量处理所有 exclude 状态的图片
      UPDATE `catalog_product_entity_media_gallery_value` SET disabled=0 WHERE disabled=1;

      3. 导出导入 Magento 所有分类和产品
      分类和产品是存放在以 catalog 开头的所有表中,对这组表进行导出导入即可实现此功能。
      导入分类产品的 SQL 文件前注意:
      在首行加入:SET FOREIGN_KEY_CHECKS=0;
      在末行加入:SET FOREIGN_KEY_CHECKS=1;
      原因是 Magento 使用 Innodb 存储引擎。

      4. 批量修改分类的 Display Settings ——> Is Anchor 值为 No
      UPDATE `catalog_category_entity_int` set value=0 WHERE value=1 AND attribute_id=120;

      5. 清空邮件队列
      TRUNCATE TABLE `newsletter_queue`;
      TRUNCATE TABLE `newsletter_queue_link`;
      TRUNCATE TABLE `newsletter_queue_store_link`;
      注意:同时向上万顾客发邮件时,不要在后台查看邮件队列,不然服务器压力会很大,待邮件发完之后,

      记着清空邮件队列,这样在后台进入邮件队列就不会大量消耗服务器资源了。

      6. Magento 转移站后,经常会出现下面这个提示,运行一下下面的SQL命令即可恢复正常。
      错误提示: Notice: Undefined index: 0 app/code/core/Mage/Core/Model/Mysql4/Config.php on

      line 92
      SET FOREIGN_KEY_CHECKS=0;
      update `core_store` set store_id = 0 where code='admin';
      update `core_store_group` set group_id = 0 where name='Default';
      update `core_website` set website_id = 0 where code='admin';
      update `customer_group` set customer_group_id = 0 where customer_group_code='NOT LOGGED IN';
      SET FOREIGN_KEY_CHECKS=1;
      不过要明白,这个错误是使用了第三方数据库备份工具导致的,Magento 自带的备份功能是不会出现这个

      错误的。

      7. 根据产品的 SKU 批量将产品自定义选项设为非必填:
      UPDATE `catalog_product_option` SET is_require=0 WHERE product_id IN (SELECT entity_id FROM

      `catalog_product_entity` WHERE sku LIKE 'SKU %');

      8. 关闭/开启 所有缺货产品
      SET FOREIGN_KEY_CHECKS=0;
      UPDATE `catalog_product_entity_int` SET value=2 WHERE attribute_id=80 and entity_id IN

      (SELECT product_id FROM `cataloginventory_stock_status` WHERE stock_status=0);
      SET FOREIGN_KEY_CHECKS=1;
      其它说明:value=2 为关闭,1为开启,attribute_id 对应不同版本的产品禁用项,最后执行完命令需要

      重建分类索引。

      9. 取消所有问题邮件订阅
      UPDATE `newsletter_subscriber` SET subscriber_status=3 WHERE subscriber_id IN (SELECT

      subscriber_id FROM `newsletter_problem`);

      10. 清除产品与分类的描述与 Meta
      重置所有产品short description
      UPDATE `catalog_product_entity_text` SET value='Short Description' WHERE

      attribute_id=506;
      清除所有产品Meta
      UPDATE `catalog_product_entity_text` SET value='' WHERE attribute_id=97 OR

      attribute_id=104;
      UPDATE `catalog_product_entity_varchar` SET value='' WHERE attribute_id=103 OR

      attribute_id=105;
      清除所有产品URL
      UPDATE `catalog_product_entity_varchar` SET value='' WHERE attribute_id=481;
      清除所有分类描述:
      UPDATE `catalog_category_entity_text` SET value='' WHERE attribute_id=112 OR

      attribute_id=115 OR attribute_id=116;
      清除所有分类URL
      UPDATE `catalog_category_entity_varchar` SET value='' WHERE attribute_id=479;

      11. 重置 Magento 所有 ID 统计数(如订单编码、发票编码等)
      TRUNCATE `eav_entity_store`;
      ALTER TABLE `eav_entity_store` AUTO_INCREMENT=1;

      12. 批量禁用产品 —— 数据库操作
      CREATE TABLE XYTMPTB SELECT entity_id,value FROM `catalog_product_entity_varchar` WHERE

      value LIKE 'affliction%' AND attribute_id=96;
      UPDATE `catalog_product_entity_int` SET value=1 WHERE attribute_id=273 AND entity_id IN

      (SELECT entity_id FROM `XYTMPTB`);
      DROP TABLE XYTMPTB;
      别忘了重建索引!

      13. 分类与产品的反向开关
      UPDATE `catalog_category_entity_int` SET value=if(value=0,1,0) WHERE attribute_id=119;
      UPDATE `catalog_product_entity_int` SET value=if(value=1,2,1) WHERE attribute_id=273;
      运行一下,开的关了,关的开了,再运一下反之,最后别忘了重建索引!

      14. 清站相关提示
      能在后台清理的就在后台清理,直接对数据库操作有造成网站出错的可能性。其他辅助命令如下:
      清除订单命令:
      TRUNCATE `sales_flat_invoice`;
      TRUNCATE `sales_flat_invoice_grid`;
      TRUNCATE `sales_flat_invoice_item`;
      TRUNCATE `sales_flat_order`;
      TRUNCATE `sales_flat_order_address`;
      TRUNCATE `sales_flat_order_grid`;
      TRUNCATE `sales_flat_order_item`;
      TRUNCATE `sales_flat_order_payment`;
      TRUNCATE `sales_flat_order_status_history`;
      TRUNCATE `sales_flat_quote`;
      TRUNCATE `sales_flat_quote_address`;
      TRUNCATE `sales_flat_quote_address_item`;
      TRUNCATE `sales_flat_quote_item`;
      TRUNCATE `sales_flat_quote_item_option`;
      TRUNCATE `sales_flat_quote_payment`;
      TRUNCATE `sales_flat_quote_shipping_rate`;
      清除其它日志:
      TRUNCATE `log_url_info`;
      TRUNCATE `log_visitor_info`;
      TRUNCATE `log_url`;
      TRUNCATE `log_visitor`;
      TRUNCATE `core_url_rewrite`;
      TRUNCATE `report_event`;
      TRUNCATE `report_viewed_product_index`;

      15. Magento 数据库清理

      安全模式:清理日常数据库的无用记录
      TRUNCATE TABLE `log_visitor`;
      TRUNCATE TABLE `log_visitor_info`;
      TRUNCATE TABLE `log_url`;
      TRUNCATE TABLE `log_url_info`;
      干净模式:清理数据库的无用记录
      TRUNCATE `log_visitor` ;
      TRUNCATE `log_url_info` ;
      TRUNCATE `log_visitor_info` ;
      TRUNCATE `dataflow_batch_import` ;
      TRUNCATE `log_url` ;
      TRUNCATE `report_event` ;
      TRUNCATE `log_visitor_online` ;
      备注:如果是转移网站,URL 重写表 core_url_rewrite 也可清空,转完站重建 URL 即可。

      16. 批量修改 SKU、Meta、Name 等字段里的部份词
      UPDATE `catalog_product_entity` SET sku=replace(sku,'oldskuw','newskuw') WHERE sku LIKE

      '%oldskuw%';
      UPDATE `catalog_product_entity_text` SET value=replace(value,'oldmetaw','newmetaw')

      WHERE value LIKE '%oldmetaw%';
      UPDATE `catalog_product_entity_varchar` SET value=replace(value,'oldnamew','newnamew')

      WHERE value LIKE '%oldnamew%';

      17. 批量调整指定产品的价格
      create table xytmptb SELECT entity_id,value FROM `catalog_product_entity_varchar` WHERE

      (value LIKE '%Boot%' OR value LIKE '%Shoes%') AND attribute_id=60;
      UPDATE `catalog_product_entity_decimal` SET value=value+10 WHERE entity_id IN (SELECT

      entity_id FROM `xytmptb`) AND attribute_id=64;
      drop table xytmptb;
      最后别忘了重建价格索引!

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 16 Sep 2015 04:22:09 +0000
      <![CDATA[O2O同城电子商务平台为什么能够迅速火起来]]> https://www.360magento.com/blog/o2o-platform/ “互联网+”时代在我们不知不觉中渗入到日常生活中,从一开始的摸爬滚打到现在的炉火纯青,各个O2O同城电商平台的出现,终于让我们对O2O这个新名词引起了关注。

      首先我们来看看这些O2O网购用户的需求:

          
      1. 宅男宅女,想吃零食,懒的去超市买。
      2.   
      3. 办公室的打印机碳粉用完了,电脑城离的挺远,来回耽误时间。
      4.   
      5. 尿不湿用完了,楼下小店的商品不放心,去大超市买,又没人照顾小孩。
      6.   
      7. 马上要装修房子了,本地的建材市场杂乱不堪,价格千差万别,怎么才能选到合适的?

      结果,同城几公里甚至一公里内,催生了大量的电子商务需求。2小时送货上门,货到付款,更快退换货。同城电子商务可以满足距离和本地服务的需求,传统行业入门门槛低,利润较高,单个城市的运营推广模式简单、初期投入成本较低,这是互联网资本的下一个热区。

      那么同城电子商务的优势在哪里?由于其同城的特殊属性,企业与消费者近距离接触,在信心构建方面相对来说比较容易操作,此外,媒体和线下品牌传播方面也有不可比拟的竞争优势,各类促销、线下活动的策办以及各类展会,都对品牌的宣传有很大的促进,同时,对初具规模的电子商务企业来说,往往能得到当地城市发展政策的支持与偏向,这对企业建立良好的公关环境有巨大的帮助,在以后竞争中软环境优势凸显。

      在价格方面,笔者坚信一点,如果能在时间上和信心上凸显相对的优势,同城电子商务企业就拥有5%-7%的相对溢价优势,对于网络消费,最大的价格因素已经在传统和电子商务之间区分开来,而由于快速的反应能力,在售后服务及公关事件的处理等诸多方面,同城电子商务企业都有独到的优势。

      而笔者认为,对于同城电子商务来说,对网购顾客最有利的莫过于电商平台所提供第三方服务。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 16 Sep 2015 04:02:54 +0000
      <![CDATA[任春雷扒尽电商行业七大真相]]> https://www.360magento.com/blog/ecommerce/ 【2015年9月15日,北京】微指(上海)信息科技有限公司今日在北京五洲皇冠国际酒店发布了微指商户版APP。CEO任春雷在发布会现场全面剖析了中国商业真相和商业运行本质规律,揭示了传统电子商务模式的时代局限,也为众多面临挑战与转型中的实体商家指明了发展方向。

      实体商业的断崖式难题揭示电商霸权

        发布会上,微指科技向到场的商户、嘉宾和媒体展示的视频,给大家带来了极大震撼。繁华的中关村电子大卖场开始落幕,原本著名的天河商圈出现了严重的倒闭关店潮,曾经最繁华的杭州武林路到处都是空店,从京津冀到长三角、珠三角,很多商业核心区无一例外遭遇寒流。此外很多A股上市百货公司前途未卜,截止到2015年8月国内百货商场共倒闭120余家,五大运动品牌和其他众多企业集体遭遇了滑铁卢。

        事实上,2011年以来,网购交易规模快速上升,到了2014年,中国网络购物占社会消费品零售总额的比重已跃升至10.72%。中国社会科学院信息化研究中心秘书长姜奇平先生曾经提到:每6%的商品从线下转移到线上,就会导致线下实体店的利润下降50%,就是下降一半,“任春雷用“人马矩阵”直观显示了电商正在迅速抢走传统商业的客流和利润."并且让网店店主们陷入 “不做广告没销量,做了广告没利润”的怪圈。他认为电商是信息流、现金流的垄断者,正在用手中的资源和权力在这个社会推行丛林法则,导致恶性竞争和商业退步。而微指的出现就是要拆除这个中间的控制阀门,实现B和C直接对接,面对面交易,恢复自由和平等地商业秩序。任春雷表示,传统互联网的商业交易模式是技术+功利的商业思维,不是实体商铺转型的最终方向,真正的互联网进化的结果只有一个,即最终重归一种进步的人文精神,其概括为:开放、共享、以所有人为中心。随着移动互联网的兴起,微指将致力于开创第三商业时代,建立点对点的、立体的网络,迎来真正的互联网时代。

      微指解决方案:帮助实体店数字化,立刻实现弯道超越

        微指商户版APP是一款是基于手机定位系统的移动互联网电子商务平台,它把全国所有实体店搬上了手机,形成了由实体虚拟店组成的数字化O2O商业交易平台。消费者可以在纵行天下的时候随时随地“搜索和购买”到“附近乃至全国”的商户或商品。通过微指APP,连通了消费者和实体店铺,结合了本地购物和网络购物两种优势。

      任春雷指出,目前传统电商主要有以下问题和局限:模式陈旧(传统店铺做生意的模式,与唐朝没有任何区别)、时间障碍(每天只能做半天生意)、空间障碍(只能做门前几平米的生意)、信息不对称(消费者就在你附近,可你们却彼此不知道)、无法低成本营销(没有传播途径、广告太贵、传单效果太差等)。微指将彻底解决实体商户这些问题,实现“时时都是营业高峰,家家都是黄金旺铺”。

        微指以改善中国人的生意和生活为宗旨,将联合所有的实体店主们完成一次信息化大升级,进行一场数字化的革命。彻底推翻实体店主们身上的三座大山,不再受经营时间、经营位置、信息不对称的限制,实现弯道超越,率先进入第三商业时代。

       

      微指覆盖海量交易和数据,打造包罗万象的中国商城。

        为了获得最准确的原始数据,三年来,微指的地推人员用双脚走遍中国。截止今日,微指商户版APP已经覆盖300多座城市,2000万家商户,10亿款商品信息,并实现位置、样品、价格、存量、服务等所有信息适时更新。微指帮助每一家实体店铺零成本升级为移动互联网商店,以每一家实体店铺为中心,形成了任意半径的服务圈和物流圈,每一家商户都以自己为圆心,为周围100米、500米、1000米、3000米,甚至全城,乃至全国的用户提供服务。

        在极度商品化的今天,其实很多商品就在身边,但因为信息不对称,用户们只能上网去淘,舍近求远。而通过微指客户端,手机用户以自身所处位置为圆心,形成了移动中的任意半径生活圈、信息圈。不管走在哪里,都可以搜索到身边100米,500米、1000米、3000米、甚至全城、乃至全国所有的店铺和货品。

      微指突破了位置的局限性,以个人为中心,建立起了移动中的生活圈、信息圈、服务圈,为每一个用户提供最近、最便捷的资源配置和服务供应。

        当每一条街、每一个实体店、每一件商品都通过微指客户端实现上传,使实体店不受交易时间的限制,也不受地段和位置的影响,全城所有的商铺和商品信息,都能通过微指被准确地定位和搜索,至此,一个数字化的商业世界才会呈现。

      免责声明:此文内容为本网站刊发或转载企业宣传资讯,该相关信息仅为宣传及传递更多信息之目的,不代表本网站观点,文章真实性请浏览者慎重核实!

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

       

      ]]>
      Wed, 16 Sep 2015 03:56:12 +0000
      <![CDATA[Magento后台简介]]> https://www.360magento.com/blog/magento-adminhtml/ 许多第一次使用Magento朋友都会有些手忙脚乱,最近也有不少客户问到一些关于magento后台操作的问题。这里呢,我就对magento后台做一个简短的介绍,希望能对各位有所帮助。

      Cms 内容管理,cms page包含前台内容页,比如about us 可定义url static block 静态块,定义一个block,方便在网站的任意地方调用,后台也可以同步修改。模板中调用方法<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('block_identifier')->toHtml(); ?> widget 插件,这个用的比较少,功能累似于static block,不过这个产生的内容要自动一些,比如我要新建一个挂件,显示5个最新产品,在catalog的左栏,可以在这里直接定义。 poll 投票功能。

      catalog 这里应该是最核心的内容,包括产品,分类,url,tag,评论,属性,属性集。每一点的内容都比较多。而且,不同生产环境下呈现的方式也不一样,比如多店的情况下。

      customer 用户管理 给用户分组,查看用户站内产品的内容,及活动。查看在线用户。

      promotios 促销规则,分类分类促销(购买指定分类或者属性的促销)和购物车促销(优惠码,购物车满多少减等等),可自定义条件,并且可以指定规则适用于哪个用户组的store view 和 website。

      sale 这是订单处理,包括订单列表,订单信息,订单发票,退款管理,发货等,都是国外电商的一套处理流程,还有关于税这一块的规则,很少用。

      newsletter 用户订阅列表,和订阅邮件推送设置,如果要推送订阅邮件,可以使用第三方发件,配合插件+magento的定时任务。

      reports 网站销售分析,自带的这一套比较简单,没有图表,如果想要图表显示,有成熟的插件可以使用。

      style 说一下我理解的过程吧, type="catalog/product_new" 这对应的是app/code/core/Mage/Catalog/Block/Product/New.php这个block里的方法。 name 指定这个block名字 as 指定别名 用来在模板中载入这个block $this->getChildHtml('newproductlist'); template 指定模板路径,在模板里调用block里对应的方法就可以获取到相应的产品列表,foreach打印到对应的html里即可。

      magento后台的内容比较多,我这里讲得比较浅,如果想要了解更多或者有什么疑问,欢迎到我们的官网360magento交流 。

      ]]>
      Wed, 16 Sep 2015 03:25:11 +0000
      <![CDATA[Magento网站流量飙升的seo技巧]]> https://www.360magento.com/blog/magento-seo/ 有效地利用Magento SEO配置才能发挥Magento的优势,这里360magento团队总结了一些Magento SEO技巧,希望能帮助大家提升网站流量。

      1. 基本的技术优化

      1.1. 普通设置

      Magento 是搜索引擎最友好的商用平台之一,但有几点需要关注以优化你的 Magento SEO.开始运行Magento时,激活 Server URL rewrites. 你可以找到这个选项在系统按钮下: System => Configuration => Web => Search Engines Optimization. 激活后,在这个页面上,另一个不错的选择是设置“Url Options ”下的 "Add store Code to Urls" ,在大多数情况下,把这个开关设为“No”更好。

      1.1.1. WWW vs non-WWW

      在 "Unsecure" 和 "Secure" 的下拉菜单里你可以找到 Base URL, 在那里你可以设置你更喜欢的域名。你可以选择WWW的URL或者没有WWW的URL。改变这些设置你不会建立一个重定向从www到non-www或者从non-www到www,而只是你设置的你喜欢的那一个。所以通过 .htaccess with mod_rewrite建立一个301重定向是一个好主意。除此之外,解决了 WWW vs non-WWW 的问题,这个重定向可以预防Magento被加入SID问题到你的URLs,像SID=b9c95150f7f70d6e77ad070259afa15d. 确保 Base URL 和重定向是一样的。编辑 .htaccess 文件时,你可以加入下面的代码到根目录下的重定向 index.php 中。 大约 119 行: RewriteBase / RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/ RewriteRule ^index\.php$ http://www.mydomain.com/ [R=301,L] 或者,你安装Magento的时候不是在根目录下而是在某个子目录下http://www.mydomain.com/magento/: RewriteBase /magento/ RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /magento/index\.php\ HTTP/ RewriteRule ^index\.php$ http://www.mydomain.com/magento/ [R=301,L]

      1.2. 页眉设置

      安装Magento时默认的标题是 "Magento Commerce"。为了你的Magento商店得到它应得得流量,以下你必须了然于胸: 搜索引擎着重于开头的词,所以如果你的关键字靠近页面标题的开头那你有更大的可能性让排名更好。 人们扫视结果页面,一般看开头的几个词。如果你的关键字位于页面的的开始,那你被点击的可能性就大很多。 首先你应该去掉默认的标题 "Magento Commerce". 后台点击 Configuration => Design => HTML Head. 为你的网站选一个描述性好的标题,这个标题也会在几个没有内容的页面中使用,比如 "Contact Us" 和 "Popular Search Terms". 把页面标题加到你的店名中,包括目录和商品,把你的店名放在“标题后缀”中。保持前缀空白是个不错的选择,原因上面提到过。同时保持 "Default Description" 和 "Default Keywords" 空白。对于非产品展示页面,为防止整站索引,设置 "Default Robots" 为 "NOINDEX, NOFOLLOW" 会有所帮助,但对于别的页面来说要确保设置为 "INDEX, FOLLOW". 现在我们优化你的网店页面的,好的方法是加上 new canonical tag (新的规范标签)。你可以安装 Canonical URL's for Magento Module 以便把它们加到你的head种来改进你的Magento SEO。 因某些原因Magento把未设置的meta机器人转为一个meta标签,方式如下:这种方式会造成搜索引擎一些奇怪的行为,所以我们要把它移除。要从代码中移除这些空白的meta你可以安装 Yoast MetaRobots Module.

      1.3. CMS 页面

      第一眼看上去Magento似乎缺少华丽的CMS功能,但对于大多数使用者来说这已经足够了。简单的CMS的好处之一是你能够控制页面的每一个方面。一旦你赋予每一个CMS页面一些不错的内容,选一个SEF URL鉴别者和页面标题,(同时记住1.2小节中的要点),到Meta数据标签处为每个你想要给它排名的CMS页面写上描述。 你可以保持"Keywords"栏空白。描述有一个很重要的作用:引诱人们去点击,所以确保它描述的确实是他们所要点击页面的内容,那样可以引起他们的注意。因此,唯一的好的描述就是自己手写的,如果你考虑用自动描述软件来写描述,那还不如什么也不做,让搜索引擎负责这部分。 如果你不使用meta描述,搜索引擎会在你的文件里找到关键字,并自动选择一条,那样在结果页面里会有一到两个醒目的词。

      1.4. 商品目录优化

      Magento 给你增加目录名的权利,让你的目录指向产品的URL。因为Magento对建立相同的内容这个功能的支持不够,很好的方式就是禁用它。设置它,点击System => Configuration => Catalog => Search Engine Optimization and set "Use categories path for product URL's to "no". 现在是时候设置每一个目录的细节了。点击Catalog => Manage Categories. 最重要的区域是: Meta 描述: 在这里放上吸引人的描述;记住人们会在搜索引擎的结果列表页中看到这个描述。 页面标题: 保持页面标题空白,使用目录名包括父目录。但你按照要求制作目录时,标题会象你所输入的一样,没有父目录。 URL 要点: 尝试保持短的但是关键字丰富的URL。移除没用的词象“the”,“and","for"等等。要注意的是你只能在“all store views”下设置, 对于多语种的商店你应该保持语言的独立。 对于每一个商店界面,你可以指定名字,描述,页面标题和Meta数据。对多语种商店来说这真的是一个很棒的功能。

      1.5. 商品优化

      商品页面的优化和目录优化有些相似。你可以设置Meta信息为 "Default Values" 并使用于每一个 "Store View". 注意对于 "Meta Title", 这个将写在完全的页面标题上,包括目录但不包括标题的前缀/后缀,而不仅仅是商品的名称。 Magento SEO中一个经常忽略的方面是你怎么处理你的图片。通过给图片写标签和考虑给你的图片起怎样的名字,你会从不同的图片搜索引擎得到不错的额外流量。

      2.Magento模板优化

      2.1. 优化了的空白模板

      默认的Magento皮肤如 "Default Theme", "Blue Skin" 和 "Modern Theme" 在标题方面的工作做得不好,从SEO的角度来看,有很多的地方可以改进。为使它对你变得简单,我们开发了一款空白的Magento SEO模板,基于Magento的核心技术,空白模板合并了所有的东西,你可以下载并一起讨论它 download and discuss it here.

      2.2. 标题

      默认的 logo 是一个 <h1>, 应该只是出现在首页,在别的页面上它应该是一个<h3>. 最重要的事实让标题的内容置于 <h1> 标签之中,例如,在目录页它应是目录名在商品也应是商品名。 下一步是清除过量的标题。一个好主意是清除侧栏的标题,或者做一个和商店相关的文字(包括关键字)。没有什么理由加上"static" 和没有什么关键字的标题在<h4>中. 是的,例如,把所有的 <h4> 标签换成 <div> to <strong> 标签更好。现在是时候优化你的内容了,在目录页中把商品名放在 <h3> 里,把目录名放在 <h1>里。在商品页,你应该把商品名放在<h1>里. 想了解更多关于为什么正确的标题是重要的,可以阅读这篇文章 Semantic HTML and SEO.

      2.3. 清除你的代码

      保持你的模板清爽,把你的模板文件中的所有 javascript 和 CSS 移到外部的 javascripts 和css 文件中,因为它们对你的Magento SEO没有任何好处。这样做可以确保你的用户在首次读取文件的时候储存那些文件,搜索引擎不需要花费大量的时间来下载它们。

      3. 高级Magento SEO 和重复内容

      一旦你完成了所有基础的东西你会发现剩下的事情就是一件简单的事:相同的内容。实际上是大量的相同的内容。商品里有相同的内容,至少,在下面的URLs有完全相同的内容:

      domain.com/product.html domain.com/category1/product.html domain.com/catalog/product/view/id/1/ domain.com/catalog/product/view/id/1/category/1/ 此外,商品回顾页面有几乎一样的内容。另一个问题是目录,你有大量相同的内容在层级导航中和索引选择中。最坏的情况是一个商品在这个页面显示之外,至少还会在这个页面以外的4个页面中显示。 我们可以通过去掉这些相同的内容,并允许它们被蜘蛛爬但不被索引,固定目录的索引选择和层级导航。

      3.1. 无内容页面的Noindex, follow

      安装 Yoast robots meta module 并确保设置成防止索引所有的无内容页面,现在搜索引擎将通过所有的链接来到这些页面上但不会再索引中显示这些页面。

      3.2. Nofollowing 非必需的链接

      另一简单的步骤来提高你的 Magento SEO 是停止链接到你的登录,付款,希望购买列表和所有其他没有内容的页面。对于RSS feeds,层级导航,增加商品到希望购买列表,增加商品到比较列表来说也是同样的设置。目前还没有插件来完成这些工作。你不得不进入你的模板文件中手工完成。

      3.3. 规范的URLs

      帮助搜索引擎理解你页面中的相同内容,你可以在每个页面使用你更喜欢的URL,使用新的 canonical URL tag (规范的URL标签),你就应该安装这个 Canonical URL's for Magento 模数。

      3.4. XML 地图

      XML 地图是让搜索引擎知道你的内容在哪里的简单方法,它不会帮助你提高排名,但它可以帮助你更快得到索引。你可以手工建立一个XML地图,后台点击 Catalog => Google Sitemap => Add Sitemap, 选择一个文件名,路径和商店界面,然后点击 "Save & Generate"。然后你可以简单的把下面的代码放到你的 robots.txt 文件中指引搜索引擎向你的 sitemap.xml 文件: Sitemap: /sitemap.xml 如果你的目录更改了,记得去重新生成XML地图。

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 16 Sep 2015 03:00:52 +0000
      <![CDATA[Magento seo小技巧]]> https://www.360magento.com/blog/magento-seo-addpage/ 当在Magento后台创建一个新页面,特别是产品页面、普通页面和博客页面的时候,对页面进行SEO显得尤为重要,因为这涉及到整个网站的长尾关键词分布,是整个网站SEO极为重要的一环。

      1.产品页面SEO

      Magento后台添加产品页面的时候,产品的标题(Name)应尽量包含产品品牌、型号、应用、特点等字词;产品描述(Description)和产品简介(Short Description)最好再次写下产品标题中最重要的关键词,增加关键词出现的频率;URL路径(URL KEY) 应包含产品品牌、型号等关键词,如“hp-lcd-panel-cq61”。 Meta信息(Meta Information)包括meta title、meta keywords和meta description三部分。其中meta title不用填写,因为产品的标题(Name)已经加入了关键词,meta title一栏留空的话系统就会让搜索引擎抓取产品标题,所以这里就不需要进行重复劳动了。当然如果你觉得产品标题容不下你想要展示的信息时,你也可以在这里添加。Meta keywords栏目应选择1至 8个关键词放在此处。产品料号、型号、品牌、应用产品、供应商、特点等都可以作为关键词。例如,hp cq61 lcd panel,B156XW02 V.0, auo , laptop lcd panel replacement;Meta description则用一两句包含meta keywords的话概括描述产品。但是实际情况是:由于产品众多,不太可能花费那么多时间去对每个产品的meta description撰写句子,所以可以整理出所有产品都适用的句式,对于不同的产品,只要更改相应的关键词即可,或者直接留空,让搜索引擎自动抓取。上传产品图片时,产品名称最好也包含相关关键词,标记(Label)可留空,让搜索引擎自动抓取产品名称作为label即可。另外,Magento还有产品标签(product tags)功能,给产品添加各种标签,搜索引擎和用户都就能更方便地找到需要的东西了。

      2.普通页面和博客页面SEO

      网站页面SEO方法大同小异,Magento产品页面方法(标题、URL路径、meta信息、图片名称)都适用于普通页面和博客页面。但是普通页面和博客页面是对文本的编辑,搜索引擎基本都是根据文本内容来爬行抓取的,所以对于文字文本的编辑也是页面SEO很重要的因素。 页面正文中应多次多出此页面标题的关键词,并且可以在第一次出现的时候加粗以示强调。同时如果正文中出现了相关关键词,可以对其设置超链接并且指向相应的页面,这样页面与页面之间就有了联系,更有利于搜索引擎蜘蛛的爬行。 如果正文中有图片,那么图片应该设置alt属性,如<img src=”hp-cq61.jpg” alt=”hp lcd panel cq61”/>。alt属性的作用是当图片无法显示时以文字作为替代显示出来,而对于SEO来说,它可以令搜索引擎有机会索引你网站上的图片。

      3.页面SEO应该注意的其他因素

      a. 太大的页面影响搜索引擎的处理速度

      b. 关键信息应该出现在页面中靠前的位置

      c. Javascript和stylesheet应该尽量放在页面外部

      d. 一个页面代码部分的体积不要太大,控制在100kb内为佳

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 16 Sep 2015 02:43:43 +0000
      <![CDATA[服装店magento主题模板]]> https://www.360magento.com/blog/clothes-store/ 响应式magento模板主题

        在上篇文章里为大家推荐了一款时尚皮包的magento主题模板,受到了不少读者的青睐。今天呢,为大家强力推荐一款服饰主题的模板。当今社会随着人们生活品质的提高,对衣着的要求也越来越高,这也意味着服装店网站也需要更加吸引顾客才行。下面我们一起来看看这款magento主题模板。

        作为一款优秀的magento主题模板,响应式是必须的。本模板完美支持智能手机和平板电脑,在不同设备上享受不同的视觉盛宴。网站主体为简约低调的灰白风格,时尚而富有贵族气息。搜索、登录、购物车、语言切换等功能皆安置在小巧的图标里,如需使用点击即可,如图是登录等功能:

      响应式magento模板主题

        强大的Megamenu插件也也是不可缺少的,看看展示的效果就能让你心动不已。

      响应式magento模板主题

        为了能更好,更多地展示出特色产品,本模版首页包含了两个幻灯片,欢迎大家点击http://www.360magento.com/magento-theme/theme027.html查看。

      另外,值得一提的是最新产品的展示,请看下图:

      响应式magento模板主题

        服装的各种款式、颜色只需轻轻点击即可切换观看,简单方便,大大节省顾客挑选产品的时间,给顾客更加友好的体验。更多功能就不一一介绍,由您自己去体验。

        如有需要,360magento团队会为您提供magento建站,插件开发等优质服务,满足您的多钟需求,解决您所遇到的各种困难。

      ]]>
      Tue, 15 Sep 2015 12:07:22 +0000
      <![CDATA[时尚经典包包magento主题模板推荐]]> https://www.360magento.com/blog/magento-handsbag/ 响应式magento模板主题

        Magento作为世界上最优秀的模板之一,正逐步地引起了过人的重视,越来越多的大小型企业选择magento作为网站的开发模板,也广受好评。众所周知的,网络的发展势不可挡,网站作为企业的门户也带来了很可观的受益。因此,选择一个优质的,符合企业需求的模版便成了网站建设的一大重点。今天就为大家推荐一个为皮包厂商量身定做的主题模版。

        这款模板在360magento官网(www.360magento.com)中的名字是“Stylish Bags Boutique Magento 主题模板”。大家可点击http://www.360magento.com/magento-theme/theme023.html来查看模板的演示效果。主题模板以橙、灰、白三色为主调,简约而符合皮包特点。强大的Megamenu能在导航中添加广告,告别传统导航仅仅只有单调文字的过去,其强大功能也只有用过的人才能体会一二。首页超大的幻灯片更是将网站特色产品尽显客户眼底。最新产品的展示也以滚动的形式展现出来,更多的产品,更小的空间,有利于顾客良好的体验。博客功能使得商家与客户的交流更加密切,商家可利用此功能普及客户对皮包的认识,让客户能更好地做出选择。

        至于其它更多功能我就不再一一列举,欢迎各位在演示网站中去体验。 如有需要,360magento团队会为您提供magento建站,插件开发等优质服务,满足您的多钟需求,解决您所遇到的各种困难。

      ]]>
      Mon, 14 Sep 2015 15:25:32 +0000
      <![CDATA[magento中避免jQuery与其它库冲突]]> https://www.360magento.com/blog/avoid-conflicts-other-libraries/ 大家都知道,在magento中用的js库是prototype,而现在我们想用jQuery,那么这就涉及到兼容性问题了,因为prototype控制着magento默认的所有js效果,我们不可能去花费大量时间去把prototype替换成jQuery,这样代价太大了,下面就在magento中jQuery兼容prototype解决方法做下讲解

      jQuery命名空间里包含了它的库和所有插件。一般来说,全局对象存储在jQuery的命名空间里,所以不应该与其它库发生冲突(比如 prototype.js, MooTools,或者YUI)

      也就是说,这里警告大家:默认地,jQuery使用$作为jQuery的缩写。因此,如果你正使用JavaScript库中的$变量,那么就会与jQuery冲突。为 了避免这些冲突,你需要在jQuery载入页面和被使用前进入无冲突模式(no-conflict mode)。

      让jQuery进入无冲突模式

      当你让jQuery进入无冲突模式时,你可以用一个新的变量名来代替$别名。

      
      <!-- Putting jQuery into no-conflict mode. -->
      <script type="text/javascript" src="prototype.js"></script>
      <script type="text/javascript" src="jquery.js"></scrip>
      <script type="text/javascript">// <![CDATA[
      var $j = jQuery.noConflict();
      // $j is now an alias to the jQuery function; creating the new alias is optional.
       
      $j(document).ready(function() {
          $j( "div" ).hide();
      });
       
      // The $ variable now has the prototype meaning, which is a shortcut for
      // document.getElementById(). mainDiv below is a DOM element, not a jQuery object.
      window.onload = function() {
          var mainDiv = $( "main" );
      }
      // ]]></script>
      

      在上面的代码中,$的意思会在原始库中被还原。使用jQuery函数全名和新别名$j效果是一样的。新的别名可以任由你命名,比如:jq, $J, awesomeQuery,等等。

      最后,如果你不愿意替换掉jQuery函数名(超喜欢用$而不在乎其它库中的$方法),这里也有个方法你可以试试:简单地将$作为参数传到你的jQuery( document ).ready()方法中。这是最常用的技能利用jQuery代码简洁优势,又能避免冲突的方法。

      
      <!-- Another way to put jQuery into no-conflict mode. -->
      <script type="text/javascript" src="prototype.js"></script>
      <script type="text/javascript" src="jquery.js"></script>
      <script type="text/javascript">// <![CDATA[
      jQuery.noConflict();
       
      jQuery( document ).ready(function( $ ) {
          // You can use the locally-scoped $ in here as an alias to jQuery.
          $( "div" ).hide();
      });
       
      // The $ variable in the global scope has the prototype.js meaning.
      window.onload = function(){
          var mainDiv = $( "main" );
      }
      // ]]></script>
      

      对于大部分你的代码,这可能是理想的解决方式。考虑到一些少部分情况,你将要做些改变去达到完全兼容的效果。

      在其它库前载入jQuery库

      上面例子中,依赖jQuery的代码在prototype.js之后被读取。如果在其它库前载入jQuery,你就可以在jQuery作用的地方使用jquery,但是$会有其它库中定义的意思。这样就不需要通过调用jQuery.noConflict()放弃$别名了。

      
      <!-- Loading jQuery before other libraries. -->
      <script type="text/javascript" src="jquery.js"></script>
      <script type="text/javascript" src="prototype.js"></script>
      <script type="text/javascript">// <![CDATA[
      // Use full jQuery function name to reference jQuery.
      jQuery( document ).ready(function() {
          jQuery( "div" ).hide();
      });
       
      // Use the $ variable as defined in prototype.js
      window.onload = function() {
          var mainDiv = $( "main" );
      };
      // ]]></script>
      

      引用jQuery函数摘要

      这里回顾下在冲突情况下如何引用jQuery函数

      创建一个新别名

      jQuery.noConflict()方法返回一个新的参数给jQuery函数,因此你可以在任何你想要的变量中捕捉它。

      
      <script type="text/javascript" src="prototype.js"></script>
      <script type="text/javascript" src="jquery.js"></script>
      <script type="text/javascript">// <![CDATA[
      // Give $ back to prototype.js; create new alias to jQuery.
      var $jq = jQuery.noConflict();
      // ]]></script>
      

      使用一个立即调用的函数表达式

      通过将你的代码包含进一个立即调用函数表达式可以让你继续使用标准的$;这也是jQuery插件编写的一个标准模式,这里笔者不知道其它库是否会接管$。

      
      <!-- Using the $ inside an immediately-invoked function expression. -->
      <script type="text/javascript" src="prototype.js"></script>
      <script type="text/javascript" src="jquery.js"></script>
      <script type="text/javascript">// <![CDATA[
      jQuery.noConflict();
       
      (function( $ ) {
          // Your jQuery code here, using the $
      })( jQuery );
      // ]]></script>
      

      这里要注意的是,当你使用这项技术时,你将不能在立即调用函数内使用prototype.js方法。$将是jQuery的参数。

      使用jQuery( document ).ready()函数的传递

      
      <script type="text/javascript" src="jquery.js"></script>
      <script type="text/javascript" src="prototype.js"></script>
      <script type="text/javascript">// <![CDATA[
      jQuery(document).ready(function( $ ) {
          // Your jQuery code here, using $ to refer to jQuery.
      });
      // ]]></script>
      

      或者使用更简洁的语法DOM ready函数

      
      <script type="text/javascript" src="jquery.js"></script>
      <script type="text/javascript" src="prototype.js"></script>
      <script type="text/javascript">// <![CDATA[
      jQuery(function($){
          // Your jQuery code here, using the $
      });
      // ]]></script>
      
      ]]>
      Fri, 11 Sep 2015 05:54:02 +0000
      <![CDATA[magento插件教程之计算器]]> https://www.360magento.com/blog/magento-extension-study001/ 这个案例的内容是,在magento前台输入两个数,然后输出结果。 这个案例的目的是 1.数值是如何在magento的Controllers传递到Block中的,又是如何在phtml文件中输出的。 2.controllers中的action使用。 3.了解使用form post参数和如何get参数。

      首先来看下这个案例中的文件结构
      /* 声明插件,指定codePool、插件开启状态等 */

      app/etc/modules/Alwayly_Counter.xml

      /* 模板.phtml文件中使用的方法在此文件中声明,此案例中此文件将计算结果传递到.phtml文件 */

      app/code/local/Alwayly/Counter/Block/Counter.php

      /* 我们此案例的的控制器 http://magento-root-folder/module-name/controller-name/action-neame 此例中IndexController控制器中的一个action获取counter.phtml中传来的参数,并将参数传递到Counter.php,在Counter.php中计算后将结果返回到counter.phtml输出 */

      app/code/local/Alwayly/Counter/controllers/IndexController.php

      /* 主要的插件配置文件 */

      app/code/local/Alwayly/Counter/etc/config.xml

      /* 前台显示模板的layout */

      app/design/frontend/default/default/layout/counter.xml

      * 前台模板文件,我们的form和结果最终就在这个文件输出,此文件直接使用$this->调用与其相应的block中的方法,本例中我们只使用这一个模板页面。 */

      app/design/frontend/default/default/template/counter/counter.phtml

      /* Helper此例不使用,放在这主要作用是显得气派,充门面 */

      app/code/local/Alwayly/Counter/Helper/Data.php

      我们先从简单的开始,那就先在前台的模板文件counter.phtml中写个提交的form吧

      app/design/frontend/default/default/template/counter/counter.phtml文件中代码片段(详见本例文件)

      <form action="" method="post" id="orderreport-form">
              <fieldset>
                  <ul>
                      <li>
                          <label for="NUM1"><?php echo $this->__('NUM1: ') ?><span class="required">*</span></label>
                          <input type="text" id="NUM1" name="NUM1" class="input-text required-entry validate-alphanum" />
                      </li>
                      <li>
                          <label for="NUM2"><?php echo $this->__('NUM2: ') ?><span class="required">*</span></label>
                          <input type="text" id="NUM2" name="NUM2" class="input-text required-entry validate-alphanum" />
                      </li>
                      <li>
                          <input type="submit" value="__('submit') ?>" />
                      </li>
                  </ul>
              </fieldset>
      </form>
      

      注意action="<!--?php echo Mage::getUrl('counter') ?-->" 等同于 action="<!--?php echo Mage::getUrl('counter/index/index') ?-->"

      有数据的post了,我们就在counter/index/index这个path下的indexAction中接收这个参数 app/code/local/Alwayly/Counter/controllers/IndexController.php文件中代码片段(详见本例文件)

       public function indexAction()
          {
             
              if ($this->getRequest()->isPost()){ /* 首先判断是否有post发生 */
                  $nu1 = $this->getRequest()->getParam('NUM1'); /* 截获参数 */
                  $nu2 = $this->getRequest()->getParam('NUM2');
                  Mage::register('nu1', $nu1);/* 传递到block */
                  Mage::register('nu2', $nu2);
              }
                 
              $this->loadLayout();    
              $this->renderLayout();
          }
      

      既然在controllers中有了传递到block的方法,下一步就在block中获取 app/code/local/Alwayly/Counter/Block/Counter.php文件中代码片段(详见本例文件)

      protected $nu1 = null ;
          protected $nu2 = null;
          public function showresult(){
              $this->nu1 = Mage::registry('nu1'); /* 获得从controllers中传递来的参数 */
              $this->nu2 = Mage::registry('nu2');
              return $this->nu1 * $this->nu2;
        
          } 
      

      此block文件中的showresult()方法在phtml文件中可以试用$this->直接调用。 这样我们就差最后一步就是在我们的模板文件中输出结果了在app/design/frontend/default/default/template/counter/counter.phtml文件中添加输出结果的代码

      <ul>
      <li>result:<?php echo $this->showresult(); ?></li>
      </ul>
      
      ]]>
      Sun, 06 Sep 2015 01:41:29 +0000
      <![CDATA[Magento中自定义邮寄方式]]> https://www.360magento.com/blog/custom-shipping-method-in-magento/

      在这篇文章中我将演示如何在Magento中编写自定义的邮寄方式。准确说来分为标准邮寄(standard shipping)和快递邮寄(express shipping)。只有当你购买的产品超过指定重量时才可能邮寄。首先说明下Magento如何处理邮寄以及为完成我们的目标需要些什么。

      当寻找可用的邮寄方式是,Magento首先收集所有可用的载体(carriers)。一个“Carrier” 代表一个承运商,就像现实世界中的(例如联邦快递)。每一个载体都被表现在扩展自Mage_Shipping_Model_Carrier_Abstract的类。

      在列出接受的载体后,邮寄方式信息(表现为Mage_Shipping_Model_Rate_Request)被送到载体去检索所有可用的费率,结果表现在Mage_Shipping_Model_Rate_Result。

      这个过程发生在Mage_Shipping_Model_Shipping::collectRates()的这段代码里:

      
      ...
      $carriers = Mage::getStoreConfig('carriers', $storeId);
       
      foreach ($carriers as $carrierCode => $carrierConfig) {
          $this->collectCarrierRates($carrierCode, $request);
      }
      ...
      

      collectCarrierRates()功能负责确认载体是否可用以及触发你的类中的collectRates()功能。 这大致就是在屏幕后所发生的事。现在,针对上面所讲我们要写一些代码。首先你要做的就是创建一个基于Mage_Shipping的模型。除了标准的模型配置外你还需要将以下代码放入你的config.xml:

      
      <config>
          ...
          <default>
              ...
              <carriers>
                  <alwayly_shipping>
                      <active>1</active>
                      <model>alwayly_shipping/carrier</model>
                      <title>Alwayly Shipping Carrier</title>
                      <sort_order>10</sort_order>
                      <sallowspecific>0</sallowspecific>
                      <express_max_weight>1</express_max_weight>
                  </alwayly_shipping>
              </carriers>
              ...
          </default>
          ...
      </config>
      

      sallowspecific和express_max_items配置条目,我们稍后解释。我们将从模型条目开始。如你所见,我们的载体表现在 Alwayly_Shipping_Model_Carrier,所以让我们实现在个类吧。前面提到的,载体需要扩展自Mage_Shipping_Model_Carrier_Abstract 并且实现Mage_Shipping_Model_Carrier_Interface来确认Magento能使用它。我们将以下面的代码开始:

      
      class Alwayly_Shipping_Model_Carrier
          extends Mage_Shipping_Model_Carrier_Abstract
          implements Mage_Shipping_Model_Carrier_Interface
      {
          protected $_code = 'alwayly_shipping';
      

      接着,getAllowedMethods() 以key-value 形式的数组返回所有可用的方法。这正是我们的接口需要的,我们这么实现:

      
      public function getAllowedMethods()
      {
          return array(
              'standard'    =>  'Standard delivery',
              'express'     =>  'Express delivery',
          );
      }
      

      最后,我说过费率被collectRates()收集。这个功能将邮寄信息转换为字段,返回所有可用的费率。它还确定哪些费率可用于给定的要求。

      
      public function collectRates(Mage_Shipping_Model_Rate_Request $request)
      {
      	/** @var Mage_Shipping_Model_Rate_Result $result */
      	$result = Mage::getModel('shipping/rate_result');
       
      	/** @var Alwayly_Shipping_Helper_Data $expressMaxProducts */
      	$expressMaxWeight = Mage::helper('alwayly_shipping')->getExpressMaxWeight();
       
      	$expressAvailable = true;
      	foreach ($request->getAllItems() as $item) {
      	    if ($item->getWeight() > $expressMaxWeight) {
      		$expressAvailable = false;
      	    }
      	}
       
      	if ($expressAvailable) {
      	    $result->append($this->_getExpressRate());
      	}
      	$result->append($this->_getStandardRate());
       
      	return $result;
      }
      

      如你所见,代码很明了。购物车里的产品重量都和设定的值做对比,由此来决定是否用快递费率每一种费率都是通过Mage_Shipping_Model_Rate_Result_Method 对象到append()这个我们的结果对象。我们通过alling _getExpressRate()和_getStandardRate()来获取这些费率对象,下面是代码:

      
      protected function _getStandardRate()
      {
          /** @var Mage_Shipping_Model_Rate_Result_Method $rate */
          $rate = Mage::getModel('shipping/rate_result_method');
       
          $rate->setCarrier($this->_code);
          $rate->setCarrierTitle($this->getConfigData('title'));
          $rate->setMethod('large');
          $rate->setMethodTitle('Standard delivery');
          $rate->setPrice(1.23);
          $rate->setCost(0);
       
          return $rate;
      }
      

      功能类已经完成。我们最后通过system.xml文件来添加后台配置。这里是代码的缩略版:

      
      <config>
          <sections>
              <carriers>
                  <groups>
                      <alwayly_shipping translate="label">
                          ...
                          <fields>
                              <active translate="label">
                                  ...
                              </active>
                              <title translate="label">
                                  ...
                              </title>
                              <sallowspecific translate="label">
                                  ...
                                  <frontend_type>select</frontend_type>
                                  <frontend_class>shipping-applicable-country</frontend_class>
                                  <source_model>adminhtml/system_config_source_shipping_allspecificcountries</source_model>
                                  ...
                              </sallowspecific>
                              <specificcountry translate="label">
                                  ...
                                  <frontend_type>multiselect</frontend_type>
                                  <source_model>adminhtml/system_config_source_country</source_model>
                                  ...
                              </specificcountry>
                              <express_max_weight translate="label">
                                  ...
                              </express_max_weight>
                          </fields>
                      </alwayly_shipping>
                  </groups>
              </carriers>
          </sections>
      </config>
      

      值得注意的是,active, title, sallowspecific 和specificcountry是被Magento自动处理的。所以除了把这些添加到后台外你什么也不用做。这里有两个有趣的选项,第一个是sallowspecific,告诉Magento运营商是否对所有国家可用,或者只针对specificcountry中指定的国家。这样,在支付页面添加邮寄方式的需求就实现了。

      声明:这篇文章原文写于2009。

      360团队与您同在

      ]]>
      Fri, 28 Aug 2015 12:49:13 +0000
      <![CDATA[在提示框里显示Magento表单验证错误信息]]> https://www.360magento.com/blog/show-validation-error-messages/

      这是一个小技巧,它可以快速地提高你的表单验证错误信息,并且在提示框里显示。

      这里不需要做任何的模版修改,你所要做的只是编辑你的CSS文件,用自定义代码来更新它。

      当错误信息被触发,Magento会注入一个class为"validation-advice"的div,这就是我们要在Css文件中修改的class。

      它必须相对于它的容器(input-box)来绝对定位。

      所以,在你的styles.css文件中找到class .validation-advice(大约在300行左右),用以下的代码来替代它:

      
      /* Form Validation */
      .input-box {
      	position: relative !important;
      }
      .validation-advice {
      	background: #DB6D00;
      	bottom: -7px;
      	color: #fff;
      	font-size: 11px;
      	font-weight: bold;
      	line-height: 13px;
      	min-height: 13px;
      	padding: 10px;
      	position: absolute;
      	right: -150px;
      	width: 120px;
      	border-radius: 5px;
      	box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
       
      }
      .validation-advice:after {
      	position: absolute;
      	left: -8px;
      	bottom: 8px;
      	content: " ";
      	width: 0;
      	height: 0;
      	border-top: 8px solid transparent;
      	border-bottom: 8px solid transparent;
      	border-right: 8px solid #DB6D00;
      }
      

      请注意这段代码应该重写“.validation-advice” class并作用于Magento默认的主题。如果你有不同的主题,这段代码可能显示的效果不一样。

      360团队与您同在……

      ]]>
      Fri, 28 Aug 2015 12:41:45 +0000
      <![CDATA[Magento中获取当前用户角色]]> https://www.360magento.com/blog/get-the-current-customer-role/ magento获取用户角色

      回顾以前些的文章,我有时能找到一些很有用的东西。其中之一是一段代码,它能对指定的客户群进行自定义操作。 在Magento后台,我们可以找到客户群。

      • 客户群管理 Customers->Customer Groups
      • 修改客户所在的群 Customers->Manage Customers->Click on a customer->Account Information tab->Customer group dropdown

      首先你要注册你的模型。我假设你已经知道如何完成,或者你已经有现成的可用。

      现在,为你的模型创建一个配置文件。我这里使用的示例模型是存在于'Alwayly'命名空间下的'Customergroup‘,下面是代码:

      app/code/community/Alwayly/Customergroup/etc/config.xml

      
      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Customergroup>
                  <version>1.0.0</version>
              </Alwayly_Customergroup>
          </modules>
          <global>
              <events>
                  <controller_action_layout_generate_blocks_after>
                      <observers>
                          <alwayly_customergroup>
                              <type>singleton</type>
                              <class>alwayly_Customergroup_Model_Observer</class>
                              <method>placeCustomJs</method>
                          </alwayly_customergroup>
                      </observers>
                  </controller_action_layout_generate_blocks_after>
              </events>
          </global>
      </config>
      

      然后,我们创建观察者。

      app/code/community/Alwayly/Customergroup/Model/Observer.php

      
      <?php
      class Alwayly_Customergroup_Model_Observer
      {
          public function placeCustomJs()
          {
       
              $roleId = Mage::getSingleton('customer/session')->getCustomerGroupId();
              $role = Mage::getSingleton('customer/group')->load($roleId)->getData('customer_group_code');
              $role = strtolower($role);
       
              $headBlock = Mage::app()->getLayout()->getBlock('head');
              if($headBlock && $role=='wholesale')
              {
                  $headBlock->addJs('test/myScript.js');
              }
              return $this;
          }
      }
      

      我展示只是一种用例。你可以在任何合适的地方使用它。比如给特定的用户组显示一条信息,一个不一样的订阅框,等等……

      一定要注意:如果用户没有登录,$role将会等于 ‘not logged in‘。

      声明:这篇文章最初写于2009年,如有问题请及时联系我们。

      360magento团队期待与您的相会:)

      ]]>
      Thu, 27 Aug 2015 08:08:55 +0000
      <![CDATA[ Magento中添加自定义信用卡类型到支付方式]]> https://www.360magento.com/blog/adding-custom-credit-card-type/ 添加自定义信用卡类型

      在某一时刻,你也许会在Magento中添加一个自定义的信用卡支付方式。请注意,在这篇Magento教程里,你将学会如何创建和验证一个新的信 用卡类型。另外,本文并不包括整个的创建支付模型过程。

      根据这篇文章提到的需求,我们假设要创建的支付模型名字为NewModule,对应 app/etc/modules/Alwayly_NewModule.xml文件。我们将要创建Diners Club信用卡,并在服务器端和客户端 用Magento方式进行验证。

      步骤

      这里只需要几步来实现这件神奇的事。当然,每一步都至关重要。

      • 在我们的config.xml文件中添加新的信用卡类型到global payment节点;
      • 让Magento识别我们所用的支付模型
      • 在我们的模型里实现服务器端的验证
      • 实现客户端的验证

      添加新的信用卡类型

      让我们创建etc/config.xml,添加下面的代码来添加信用卡类型:

      
      <config>
          <modules>
              <Alwayly_NewModule>
                  <version>1.0.0</version>
             </Alwayly_NewModule>
          </modules>
       
          <global>
              <payment>
                  <cc>
                      <types>
                          <DC>
                              <code>DC</code>
                              <name>Diners Club</name>
                              <order>60</order>
                          </DC>
                      </types>
                  </cc>
              </payment>
          </global>
      </config>
      

      到这里,我们只是添加了一个信用卡类型到Magento,并没有说明它所用的模型以及如何验证它。

      创建支付模型

      让我添加一些代码到etc/config.xml来配置我们的模型并告知Magento,代码如下:

      
      <config>
        ...
          <global>
            ...
              <models>
                  <newmodule>
                      <class>Alwayly_NewModule_Model</class>
                  </newmodule>
              </models>
            ...
          </global>
       
          <default>
              <payment>
                  <newmodule>
                      <model>newmodule/payment</model>
                  </newmodule>
              </payment>
          </default>
      </config>
      

      现在,我们要创建Alwayly/NewModule/Model/Payment.php文件。包含扩展了Mage_Payment_Model_Method_Cc的类。在这个文件中,我们要将自己定义的正则表达式应用到信用卡号和CVV(信用卡验证码)。如果你想实现一个不同的信用卡类型,你就需要一个与之匹配的正则表达式。

      
      class Alwayly_NewModule_Model_Payment extends Mage_Payment_Model_Method_Cc
      {
          protected $_code = 'alwayly_newmodule';
       
          public function getVerificationRegEx()
          {
              return array_merge(parent::getVerificationRegEx(), array(
                  'DC' => '/^[0-9]{3}$/' // Diners Club CCV
             ));
          }
       
          public function OtherCcType($type)
          {
              return in_array($type, array('OT', 'DC'));
          }
       
          public function validate()
          {
              parent::validate();
              /* we call parent's validate() function!
               * if the code got this far, it means the cc type is none of the supported
               * ones implemented by Magento and now it gets interesting
               */
       
              $info = $this->getInfoInstance();
              $ccNumber = $info->getCcNumber();
              $availableTypes = explode(',',$this->getConfigData('cctypes'));
              // checks if Diners Club card is allowed
              if(!in_array($info->getCcType(), $availableTypes)){
                  Mage::throwException($this->_getHelper()->__('Credit card type is not allowed for this payment method.'));
              }
              // validate credit card number against Luhn algorithm
              if(!$this->validateCcNum($info->getCcNumber())){
                  Mage::throwException($this->_getHelper()->__('Invalid Credit Card Number'));
              }
       
              /* this is Diners Club regex pattern.
               * it's different for every cc type, so beware
               */
              if($info->getCcType()=='DC' && !preg_match('/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/', $ccNumber)){
                  Mage::throwException($this->_getHelper()->__('Credit card number mismatch with credit card type.'));
              }
              // now we retrieve our CCV regex pattern and validate against it
              $verificationRegex = $this->getVerificationRegEx();
              if(!preg_match($verificationRegex[$info->getCcType()], $info->getCcCid()))
              {
                  Mage::throwException($this->_getHelper()->__('Please enter a valid credit card verification number.'));
              }
       
              // further validation here (expiration month, expiration year etc.)
       
          }
       
      }
      

      现在,总结一下我们的Diners Club卡号和验证码部分。你可能会想对validate()方法进一步验证,例如信用卡的到期时间。

      客户端验证 这里有两种方法可以完成这个功能。 第一种是创建一个.js文件并用布局XML包含到我们想要的地方。第二种只需要修改布局文件。 这里我们将采用第二种方式。

      
      <config>
        ...
          <frontend>
              <layout>
                  <updates>
                      <newmodule>
                          <file>newmodule.xml</file>
                      </newmodule>
                  </updates>
              </layout>
          </frontend>
      </config>
      

      是时候修改布局文件并引入javascript到checkout onepage。如果在此之前你没创建布局文件,那么用下面的代码创建它。

      design/frontend/base/default/layout/newmodule.xml

      
      <layout version="1.0.0">
          <checkout_onepage_index>
              <reference name="head">
                  <block type="core/text" name="newmodule.diners.validation">
                      <action method="setText">
                          <text>
                              <![CDATA[<script type="text/javascript">
                                  Validation.creditCartTypes.set('DC', [new RegExp('^3(?:0[0-5]|[68][0-9])[0-9]{11}$'), new RegExp('^[0-9]{3}$'), true]);
                              </script>]]>
                          </text>
                      </action>
                  </block>
              </reference>
          </checkout_onepage_index>
      </layout>
      

      在我们NewModule的config.xml中,我应该把Diners Club加入到许可的信用卡类型列表里。

      
      <config>
          ...
          <default>
              <payment>
                  <newmodule>
                      <model>newmodule/payment</model>
                      <cctypes>VI,AE,DC</cctypes> //Visa (VI), American Express (AE) and Diners Club (DC)
                  </newmodule>
              </payment>
          </default>
      </config>
      

      大功告成!我们成功地在Magento中添加了一个自定义信用卡类型。

      360magento团队竭诚为您服务:)

      ]]>
      Thu, 27 Aug 2015 03:28:17 +0000
      <![CDATA[Magento中去掉产品图片留白的方法]]> https://www.360magento.com/blog/remove-white-image-frame/ magento去图片留白

      Magento有漂亮整洁的助手能输出你的产品照片。今天,我的一位同事在尝试侧边栏展示调整后的图片时,对图片的留白有些不太顺心。他尝试过的一种解决方式是用CSS。然而,这里有一个更好的办法来去掉调整后图片周围的留白。

      这个实用例子中的代码来自默认的media.phtml

      app/design/frontend/default/you_theme/template/catalog/product/view/media.phtml

      
      <?php foreach ($this->getGalleryImages() as $_image): ?>
          <li>
              <a href="#" onclick="popWin('<?php echo $this->getGalleryUrl($_image) ?>', 'gallery', 'width=300,height=300,left=0,top=0,location=no,status=yes,scrollbars=yes,resizable=yes'); return false;" title="< ?php echo $this->htmlEscape($_image->getLabel()) ?>">
      <img src="<?php echo $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail', $_image->getFile())->resize(56); ?>" width="56" height="56" alt="<?php echo $this->htmlEscape($_image->getLabel()) ?>" />
      </a> </li> <?php endforeach; ?>

      将它改变成这样将会产生一个“框架自由”图片

      
      <?php foreach ($this->getGalleryImages() as $_image): ?>
          <li>
              <a href="#" onclick="popWin('<?php echo $this->getGalleryUrl($_image) ?>', 'gallery', 'width=300,height=300,left=0,top=0,location=no,status=yes,scrollbars=yes,resizable=yes'); return false;" title="<?php echo $this->htmlEscape($_image->getLabel()) ?>">
      <img src="<?php echo $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail', $_image->getFile())->keepFrame(false)->resize(56); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel()) ?>" />
      </a> </li> <?php endforeach; ?>

      如你所见,我们所做的只是在resize()方法前面添加keepFrame(false)方法。

      这就是脚本修改前后的结果。

      修改前 magento修改后

      希望它可以解决一些细微的样式问题。

      360Magento团队期待与您的沟通:)

      ]]>
      Wed, 26 Aug 2015 10:44:14 +0000
      <![CDATA[Magento中如何添加自定义产品关系]]> https://www.360magento.com/blog/add-custom-product-relations/ magento自定义产品关系

      目前,在Magento中有三中产品关系:Up-sells, Related Products,和Cross-sell Products。最近在讨论客户需求的时候,我们发现在Magento中创建独立的自定义产品关系能更好地实现我们的目的。在这篇文章中,我将演示如何增加自定义的Magento产品关系.

      简介

      下面,我将用Magento插件中的代码来说明一下在Magento中添加自定义产品关系的过程。

      安装脚本程序

      首先,要让Magento数据库知道我们新的产品链接类型。以下是安装脚本: app/code/community/Alwayly/CustomLinkedProducts/sql/alwayly_customlinkedproducts_setup/install-0.0.1.php

      
      <?php
       
      $installer = $this;
       
      /**
       * Install product link types
       */
      $data = array(
          array(
              'link_type_id'  => Alwayly_CustomLinkedProducts_Model_Catalog_Product_Link::LINK_TYPE_CUSTOM,
              'code'          => 'custom'
          )
      );
       
      foreach ($data as $bind) {
          $installer->getConnection()->insertForce($installer->getTable('catalog/product_link_type'), $bind);
      }
       
      /**
       * Install product link attributes
       */
      $data = array(
          array(
              'link_type_id'                  => Alwayly_CustomLinkedProducts_Model_Catalog_Product_Link::LINK_TYPE_CUSTOM,
              'product_link_attribute_code'   => 'position',
              'data_type'                     => 'int'
          )
      );
       
      $installer->getConnection()->insertMultiple($installer->getTable('catalog/product_link_attribute'), $data);
      

      后台界面

      下一步就是在后台产品信息页添加新标签。下面是相关的PHP代码,稍后我们会用我们的XML文件将它添加到布局。 app/code/community/Alwayly/CustomLinkedProducts/Block/Adminhtml/Catalog/Product/Edit/Tab.php

      
      <?php
      
      class Alwayly_CustomLinkedProducts_Block_Adminhtml_Catalog_Product_Edit_Tab
      extends Mage_Adminhtml_Block_Widget
      implements Mage_Adminhtml_Block_Widget_Tab_Interface
      {
          public function canShowTab() 
          {
              return true;
          }
       
          public function getTabLabel() 
          {
              return $this->__('Custom Linked Products');
          }
       
          public function getTabTitle()        
          {
              return $this->__('Custom Linked Products');
          }
       
          public function isHidden()
          {
              return false;
          }
       
          public function getTabUrl() 
          {
              return $this->getUrl('*/*/custom', array('_current' => true));
          }
       
          public function getTabClass()
          {
              return 'ajax';
          }
       
      }
      

      因为我们的标签指向‘*/*/custom’路由,所以我们需要将它添加到Mage_Adminhtml_Catalog_ProductController。以下是代码: app/code/community/Alwayly/CustomLinkedProducts/controllers/Adminhtml/Catalog/ProductController.php

      <?php
       
      require_once(Mage::getModuleDir('controllers','Mage_Adminhtml').DS.'Catalog'.DS.'ProductController.php');
       
      class Alwayly_CustomLinkedProducts_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController
      {
          /**
           * Get custom products grid and serializer block
           */
          public function customAction()
          {
              $this->_initProduct();
              $this->loadLayout();
              $this->getLayout()->getBlock('catalog.product.edit.tab.custom')
                  ->setProductsCustom($this->getRequest()->getPost('products_custom', null));
              $this->renderLayout();
          }
       
          /**
           * Get custom products grid
           */
          public function customGridAction()
          {
              $this->_initProduct();
              $this->loadLayout();
              $this->getLayout()->getBlock('catalog.product.edit.tab.custom')
                  ->setProductsRelated($this->getRequest()->getPost('products_custom', null));
              $this->renderLayout();
          }
       
      }
      

      为了将我们的新标签添加到后台,也为了getBlock(‘catalog.product.edit.tab.custom’)方法能作用于customAction()customGridAction()。我们需要在我们的布局里添加一点XML代码。

      
      <?xml version="1.0" encoding="UTF-8"?>
       
      <layout>
       
          <adminhtml_catalog_product_edit>
              <reference name="product_tabs">
                  <action method="addTab">
                      <name>custom</name>
                      <block>alwayly_customlinkedproducts/adminhtml_catalog_product_edit_tab</block>
                 </action>
              </reference>
          </adminhtml_catalog_product_edit>
       
          <adminhtml_catalog_product_custom>
             <block type="core/text_list" name="root" output="toHtml">
                  <block type="alwayly_customlinkedproducts/adminhtml_catalog_product_edit_tab_custom" name="catalog.product.edit.tab.custom"/>
                  <block type="adminhtml/widget_grid_serializer" name="custom_grid_serializer">
                      <reference name="custom_grid_serializer">
                          <action method="initSerializerBlock">
                              <grid_block_name>catalog.product.edit.tab.custom</grid_block_name>
                              <data_callback>getSelectedCustomProducts</data_callback>
                              <hidden_input_name>links[custom]products_custom

      接着我们要为我们的自定义产品关系标签创建一个网格,让它可以在后台显示。这有大量的代码,但大部分都是些基础的代码。唯一你所要注意的是在_prepareCollection()功能中使用useCustomLinks()。下面是代码:

      
      <?php
      
      class Alwayly_CustomLinkedProducts_Block_Adminhtml_Catalog_Product_Edit_Tab_Custom extends Mage_Adminhtml_Block_Widget_Grid
      {
          /**
           * Set grid params
           *
           */
          public function __construct()
          {
              parent::__construct();
              $this->setId('custom_product_grid');
              $this->setDefaultSort('entity_id');
              $this->setUseAjax(true);
              if ($this->_getProduct()->getId()) {
                  $this->setDefaultFilter(array('in_products' => 1));
              }
              if ($this->isReadonly()) {
                  $this->setFilterVisibility(false);
              }
          }
          /**
           * Retirve currently edited product model
           *
           * @return Mage_Catalog_Model_Product
           */
          protected function _getProduct()
          {
              return Mage::registry('current_product');
          }
          /**
           * Add filter
           *
           * @param object $column
           * @return Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Custom
           */
          protected function _addColumnFilterToCollection($column)
          {
              // Set custom filter for in product flag
              if ($column->getId() == 'in_products') {
                  $productIds = $this->_getSelectedProducts();
                  if (empty($productIds)) {
                      $productIds = 0;
                  }
                  if ($column->getFilter()->getValue()) {
                      $this->getCollection()->addFieldToFilter('entity_id', array('in' => $productIds));
                  } else {
                      if($productIds) {
                          $this->getCollection()->addFieldToFilter('entity_id', array('nin' => $productIds));
                      }
                  }
              } else {
                  parent::_addColumnFilterToCollection($column);
              }
              return $this;
          }
          /**
           * Prepare collection
           *
           * @return Mage_Adminhtml_Block_Widget_Grid
           */
          protected function _prepareCollection()
          {
              $collection = Mage::getModel('catalog/product_link')->useCustomLinks()
                  ->getProductCollection()
                  ->setProduct($this->_getProduct())
                  ->addAttributeToSelect('*');
              if ($this->isReadonly()) {
                  $productIds = $this->_getSelectedProducts();
                  if (empty($productIds)) {
                      $productIds = array(0);
                  }
                  $collection->addFieldToFilter('entity_id', array('in' => $productIds));
              }
              $this->setCollection($collection);
              return parent::_prepareCollection();
          }
          /**
           * Checks when this block is readonly
           *
           * @return boolean
           */
          public function isReadonly()
          {
              return $this->_getProduct()->getCustomReadonly();
          }
          /**
           * Add columns to grid
           *
           * @return Mage_Adminhtml_Block_Widget_Grid
           */
          protected function _prepareColumns()
          {
              if (!$this->isReadonly()) {
                  $this->addColumn('in_products', array(
                      'header_css_class'  => 'a-center',
                      'type'              => 'checkbox',
                      'name'              => 'in_products',
                      'values'            => $this->_getSelectedProducts(),
                      'align'             => 'center',
                      'index'             => 'entity_id'
                  ));
              }
              $this->addColumn('entity_id', array(
                  'header'    => Mage::helper('catalog')->__('ID'),
                  'sortable'  => true,
                  'width'     => 60,
                  'index'     => 'entity_id'
              ));
              $this->addColumn('name', array(
                  'header'    => Mage::helper('catalog')->__('Name'),
                  'index'     => 'name'
              ));
              $this->addColumn('type', array(
                  'header'    => Mage::helper('catalog')->__('Type'),
                  'width'     => 100,
                  'index'     => 'type_id',
                  'type'      => 'options',
                  'options'   => Mage::getSingleton('catalog/product_type')->getOptionArray(),
              ));
              $sets = Mage::getResourceModel('eav/entity_attribute_set_collection')
                  ->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
                  ->load()
                  ->toOptionHash();
              $this->addColumn('set_name', array(
                  'header'    => Mage::helper('catalog')->__('Attrib. Set Name'),
                  'width'     => 130,
                  'index'     => 'attribute_set_id',
                  'type'      => 'options',
                  'options'   => $sets,
              ));
              $this->addColumn('status', array(
                  'header'    => Mage::helper('catalog')->__('Status'),
                  'width'     => 90,
                  'index'     => 'status',
                  'type'      => 'options',
                  'options'   => Mage::getSingleton('catalog/product_status')->getOptionArray(),
              ));
              $this->addColumn('visibility', array(
                  'header'    => Mage::helper('catalog')->__('Visibility'),
                  'width'     => 90,
                  'index'     => 'visibility',
                  'type'      => 'options',
                  'options'   => Mage::getSingleton('catalog/product_visibility')->getOptionArray(),
              ));
              $this->addColumn('sku', array(
                  'header'    => Mage::helper('catalog')->__('SKU'),
                  'width'     => 80,
                  'index'     => 'sku'
              ));
              $this->addColumn('price', array(
                  'header'        => Mage::helper('catalog')->__('Price'),
                  'type'          => 'currency',
                  'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE),
                  'index'         => 'price'
              ));
              $this->addColumn('position', array(
                  'header'            => Mage::helper('catalog')->__('Position'),
                  'name'              => 'position',
                  'type'              => 'number',
                  'validate_class'    => 'validate-number',
                  'index'             => 'position',
                  'width'             => 60,
                  'editable'          => !$this->_getProduct()->getCustomReadonly(),
                  'edit_only'         => !$this->_getProduct()->getId()
              ));
              return parent::_prepareColumns();
          }
          /**
           * Rerieve grid URL
           *
           * @return string
           */
          public function getGridUrl()
          {
              return $this->getData('grid_url')
                  ? $this->getData('grid_url')
                  : $this->getUrl('*/*/customGrid', array('_current' => true));
          }
          /**
           * Retrieve selected custom products
           *
           * @return array
           */
          protected function _getSelectedProducts()
          {
              $products = $this->getProductsCustom();
              if (!is_array($products)) {
                  $products = array_keys($this->getSelectedCustomProducts());
              }
              return $products;
          }
          /**
           * Retrieve custom products
           *
           * @return array
           */
          public function getSelectedCustomProducts()
          {
              $products = array();
              foreach (Mage::registry('current_product')->getCustomProducts() as $product) {
                  $products[$product->getId()] = array('position' => $product->getPosition());
              }
              return $products;
          }
      }
      

      Magento后台中管理自定义产品关系的界面是这样的:

      magento自定义产品关系后台

      后端支持代码

      正如你注意到的,useCustomLinks()方法在catalog/product_link模型中是不存在的。因此,我们需要重写这个模型来添加我们自定义产品关系的功能。

      app/code/community/Alwayly/CustomLinkedProducts/Model/Catalog/Product/Link.php

      
      <?php
       
      class Alwayly_CustomLinkedProducts_Model_Catalog_Product_Link extends Mage_Catalog_Model_Product_Link
      {
          const LINK_TYPE_CUSTOM   = 6;
       
          /**
           * @return Mage_Catalog_Model_Product_Link
           */
          public function useCustomLinks()
          {
              $this->setLinkTypeId(self::LINK_TYPE_CUSTOM);
              return $this;
          }
       
          /**
           * Save data for product relations
           *
           * @param   Mage_Catalog_Model_Product $product
           * @return  Mage_Catalog_Model_Product_Link
           */
          public function saveProductRelations($product)
          {
              parent::saveProductRelations($product);
       
              $data = $product->getCustomLinkData();
              if (!is_null($data)) {
                  $this->_getResource()->saveProductLinks($product, $data, self::LINK_TYPE_CUSTOM);
              }
       
          }
      }
      

      如果你想要在同一个Magento项目中再添加一个自定义关系,那么你需要增加LINK_TYPE_CUSTOM类常量来避免冲突。现在,你也许注意到catalog/product中没有getCustomLinkData()功能。别怕,下面这段代码能解决这个问题:

      app/code/community/Alwayly/CustomLinkedProducts/Model/Catalog/Product.php

      
      <?php
       
      class Alwayly_CustomLinkedProducts_Model_Catalog_Product extends Mage_Catalog_Model_Product
      {
          /**
           * Retrieve array of custom products
           *
           * @return array
           */
          public function getCustomProducts()
          {
              if (!$this->hasCustomProducts()) {
                  $products = array();
                  $collection = $this->getCustomProductCollection();
                  foreach ($collection as $product) {
                      $products[] = $product;
                  }
                  $this->setCustomProducts($products);
              }
              return $this->getData('custom_products');
          }
       
          /**
           * Retrieve custom products identifiers
           *
           * @return array
           */
          public function getCustomProductIds()
          {
              if (!$this->hasCustomProductIds()) {
                  $ids = array();
                  foreach ($this->getCustomProducts() as $product) {
                      $ids[] = $product->getId();
                  }
                  $this->setCustomProductIds($ids);
              }
              return $this->getData('custom_product_ids');
          }
       
          /**
           * Retrieve collection custom product
           *
           * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
           */
          public function getCustomProductCollection()
          {
              $collection = $this->getLinkInstance()->useCustomLinks()
                  ->getProductCollection()
                  ->setIsStrongMode();
              $collection->setProduct($this);
              return $collection;
          }
       
          /**
           * Retrieve collection custom link
           *
           * @return Mage_Catalog_Model_Resource_Product_Link_Collection
           */
          public function getCustomLinkCollection()
          {
              $collection = $this->getLinkInstance()->useCustomLinks()
                  ->getLinkCollection();
              $collection->setProduct($this);
              $collection->addLinkTypeIdFilter();
              $collection->addProductIdFilter();
              $collection->joinAttributes();
              return $collection;
          }
       
      }
      

      还有一件重要的事情要完成:保存我们的产品关系并让它作用于产品。我们需要粘贴catalog_product_prepare_savecatalog_model_product_duplicate事件。下面是回调了这些事件的观察员类。

      
      <?php
       
      class Alwayly_CustomLinkedProducts_Model_Observer extends Varien_Object
      {
          public function catalogProductPrepareSave($observer)
          {
              $event = $observer->getEvent();
       
              $product = $event->getProduct();
              $request = $event->getRequest();
       
              $links = $request->getPost('links');
              if (isset($links['custom']) && !$product->getCustomReadonly()) {
                  $product->setCustomLinkData(Mage::helper('adminhtml/js')->decodeGridSerializedInput($links['custom']));
              }
          }
       
          public function catalogModelProductDuplicate($observer)
          {
              $event = $observer->getEvent();
       
              $currentProduct = $event->getCurrentProduct();
              $newProduct = $event->getNewProduct();
       
              $data = array();
              $currentProduct->getLinkInstance()->useCustomLinks();
              $attributes = array();
              foreach ($currentProduct->getLinkInstance()->getAttributes() as $_attribute) {
                  if (isset($_attribute['code'])) {
                      $attributes[] = $_attribute['code'];
                  }
              }
              foreach ($currentProduct->getCustomLinkCollection() as $_link) {
                  $data[$_link->getLinkedProductId()] = $_link->toArray($attributes);
              }
              $newProduct->setCustomLinkData($data);
          }
       
      }
      

      前台界面

      为了在Magento前端展示我们自定义的产品关系,我把Magento’s related products块及相关模板文件复制到alwayly_customrelatedproducts/catalog_product_list_custom块。我们复制的相关产品块将使用我们定义的产品关系。下面是前端显示效果:

      magento自定义产品关系前台

      希望能对你的项目有所帮助。

      ]]>
      Wed, 26 Aug 2015 03:19:48 +0000
      <![CDATA[Magento中列出特卖产品的方法]]> https://www.360magento.com/blog/onsale-master/ magento特价产品展示

      有些客户想要在首页显示特卖产品,或者有时想要在某个分类中筛选特卖产品。在这篇magento教程中,我将写到两种列出特卖产品的方法:

      • Magento首页作为列表显示;
      • 在产品列表页通过筛选器显示;

      让我们开始吧!

      静态CMS页面

      使用后台管理员上传一个.phtml文件是一个将特卖产品显示在某个页面的快速方法。用这个方法你将不能使用分页和导航。如果你喜欢这些功 能,我推荐这篇文章的第二部分。

      用以下内容创建一个新的CMS page

      {{block type="catalog/product_list" template="inchoo/onsale/sale.phtml"}}

      还有一个排列你产品的模版

      app/design/frontend/default/YOUR_THEME/template/alwayly/onsale/sale.phtml

      <?php
          $_productCollection = Mage::getModel('catalog/product')->getCollection();
          $_productCollection->addAttributeToSelect(array(
                                         'image',
                                         'name',
                                         'short_description'
                                                    ))
                              ->addFieldToFilter('visibility', array(
                                          Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
                                          Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
                                  )) //showing just products visible in catalog or both search and catalog
                              ->addFinalPrice()
      //                        ->addAttributeToSort('price', 'asc') //in case we would like to sort products by price
                              ->getSelect()
                              ->where('price_index.final_price < price_index.price')
      //                        ->limit(30) //we specify how many products we want to show on this page
      //                        ->order(new Zend_Db_Expr('RAND()')) //in case we would like to sort products randomly
                              ;
      
          Mage::getModel('review/review')->appendSummary($_productCollection);
          $_helper = $this->helper('catalog/output');
      ?>
      
      <?php if(!$_productCollection->count()): ?>
          <p class="note-msg"><?php echo $this->__('There are no products matching the selection.') ?></p>
      <?php else: ?>
          <div class="category-products">
              <?php // Grid Mode ?>
              <?php $_collectionSize = $_productCollection->count() ?>
              <?php $_columnCount = $this->getColumnCount(); ?>
              <?php $i=0; foreach ($_productCollection as $_product): ?>
              <?php if ($i++%$_columnCount==0): ?>
                  <ul class="products-grid" style="padding:0; list-style: none">
              <?php endif ?>
                  <li class="item<?php if(($i-1)%$_columnCount==0): ?> first<?php elseif($i%$_columnCount==0): ?> 
      
      last<?php endif; ?>">
                      <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this-
      
      >getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image"><img src="<?php echo $_product-
      
      >getImageUrl(); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 
      
      'small_image'), null, true) ?>" /></a>
                      <h2 class="product-name"><a href="<?php echo $_product->getProductUrl() ?>" title="<?php 
      
      echo $this->stripTags($_product->getName(), null, true) ?>"><?php echo $_helper->productAttribute($_product, 
      
      $_product->getName(), 'name') ?></a></h2>
                      <?php if($_product->getRatingSummary()): ?>
                          <?php echo $this->getReviewsSummaryHtml($_product, 'short') ?>
                      <?php endif; ?>
                      <?php echo $this->getPriceHtml($_product, true) ?>
                      <div class="actions">
                          <?php if($_product->isSaleable()): ?>
                              <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-
      
      cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php 
      
      echo $this->__('Add to Cart') ?></span></span></button>
                          <?php else: ?>
                              <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?
      
      ></span></p>
                          <?php endif; ?>
                          <ul class="add-to-links">
                              <?php if ($this->helper('wishlist')->isAllow()) : ?>
                                  <li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" 
      
      class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
                              <?php endif; ?>
                              <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
                                  <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?
      
      >" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
                              <?php endif; ?>
                          </ul>
                      </div>
                  </li>
                  <?php if ($i%$_columnCount==0 || $i==$_collectionSize): ?>
                  </ul>
              <?php endif ?>
              <?php endforeach ?>
              <script type="text/javascript">decorateGeneric($$('ul.products-grid'), 
      
      ['odd','even','first','last'])</script>
          </div>
      <?php endif; ?>

      完成!尝试一下,然后访问你的CMS页面。你将看到带有特价的产品以列表的形式显示出来,就像这样:

      特卖

      修改一下以后,你也可以以网格的形式展示产品。

      产品列表中的筛选器

      一个集合在被读入模版前,Magento会使用筛选器并读取到分层导航。这就是我们要重写 _getProductCollection方法的原 因,这样我们就能在集合被读取前使用自定义的筛选器。让我们扩展Mage_Catalog_Product_List类和渲染我们的块来替换分 类列表中默认的筛选器。

      让我们注册这个模型。根据作用,我们给它命名"Alwayly/Onsale"

      app/etc/modules/Alwayly_Onsale.xml

      
      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Onsale>
                  <active>true</active>
                  <codePool>local</codePool>
              </Alwayly_Onsale>
          </modules>
      </config>
      

      接着配置我们的模型。我们将用到块(block),助手(helper)并对我们模版的布局进行一点修改。

      app/code/local/Inchoo/Onsale/etc/config.xml

      
      <?xml version="1.0"?>
      <config>
          <modules>
              <Alwayly_Onsale>
                  <version>1.0.0.3</version>
              </Alwayly_Onsale>
          </modules>
          <global>
              <blocks>
                  <alwayly_onsale>
                      <class>Alwayly_Onsale_Block</class>
                  </alwayly_onsale>
              </blocks>
              <helpers>
                  <alwayly_onsale>
                      <class>Alwayly_Onsale_Helper</class>
                  </alwayly_onsale>
              </helpers>
          </global>
          <frontend>
              <layout>
                  <updates>
                      <onsale>
                          <file>alwayly/onsale.xml</file>
                      </onsale>
                  </updates>
              </layout>
          </frontend>
      </config>
      

      现在,注册一个包含getOnSaleUrlgetNotOnSaleUrl方法的助手。这两个方法将被用来获取我们复选框 中链接的地址。我们将添加一个新的变量-"Sale"到网址。当sale等于1的时候,我们将显示特卖的产品,如果没有被设置就会显示这个类中的所 有产品。

      app/code/local/Inchoo/Onsale/Helper/Data.php

      <?php
      class Alwayly_Onsale_Helper_Data extends Mage_Core_Helper_Abstract
      {
          public function getOnSaleUrl()
          {
              $url = Mage::getUrl('', array(
                  '_current' => true,
                  '_use_rewrite' => true,
                  '_query' => array(
                      'sale' => 1,
                      'p' => NULL
                  )
              ));
       
              return $url;
          }
       
          public function getNotOnSaleUrl()
          {
              $url = Mage::getUrl('', array(
                  '_current' => true,
                  '_use_rewrite' => true,
                  '_query' => array(
                      'sale' => NULL,
                      'p' => NULL
                  )
              ));
       
              return $url;
          }
      }
      

      接着让我们创建我们的块。我们将从Mage_Catalog_Block_Product_List扩展我们的类并添加 _getProductCollection方法。

      app/code/local/Alwayly/Onsale/Block/Catalog/Product/List.php

      
      <?php
      class Alwayly_Onsale_Block_Catalog_Product_List extends Mage_Catalog_Block_Product_List
      {
          protected function _getProductCollection()
          {
              if (is_null($this->_productCollection)) {
                  $layer = $this->getLayer();
                  /* @var $layer Mage_Catalog_Model_Layer */
                  if ($this->getShowRootCategory()) {
                      $this->setCategoryId(Mage::app()->getStore()->getRootCategoryId());
                  }
       
                  // if this is a product view page
                  if (Mage::registry('product')) {
                      // get collection of categories this product is associated with
                      $categories = Mage::registry('product')->getCategoryCollection()
                                        ->setPage(1, 1)
                                        ->load();
                      // if the product is associated with any category
                      if ($categories->count()) {
                          // show products from this category
                          $this->setCategoryId(current($categories->getIterator()));
                      }
                  }
       
                  $origCategory = null;
                  if ($this->getCategoryId()) {
                      $category = Mage::getModel('catalog/category')->load($this->getCategoryId());
                      if ($category->getId()) {
                          $origCategory = $layer->getCurrentCategory();
                          $layer->setCurrentCategory($category);
                          $this->addModelTags($category);
                      }
                  }
                  $this->_productCollection = $layer->getProductCollection();
       
      //                inchoo start
                  $param = Mage::app()->getRequest()->getParam('sale');
                  if(isset($param) && $param==='1'){
                      $this->_productCollection
                          ->addFinalPrice()
                          ->getSelect()
                          ->where('price_index.final_price < price_index.price');
                  }
      //                inchoo end
       
                  $this->prepareSortableFieldsByCategory($layer->getCurrentCategory());
       
                  if ($origCategory) {
                      $layer->setCurrentCategory($origCategory);
                  }
              }
       
              return $this->_productCollection;
      //            return parent::_getProductCollection();
          }
      }
      

      我们还要在工具栏中添加一个复选框来让顾客筛选特卖产品。打开我们的toolbar.phtml文件。

      app/design/frontend/default/YOUR_THEME/template/alwayly/onsale/toolbar.phtml

      
      <!--alwayly start-->
      <?php $helper = Mage::helper('alwayly_onsale'); ?>
      <!--alwayly end-->
      <?php if($this->getCollection()->getSize()): ?>
          <div class="toolbar">
              <div class="pager">
                  <p class="amount">
                      <?php if($this->getLastPageNum()>1): ?>
                          <?php echo $this->__('Items %s to %s of %s total', $this->getFirstNum(), $this->getLastNum(), 
      
      $this->getTotalNum()) ?>
                      <?php else: ?>
                          <?php echo $this->__('%s Item(s)', $this->getTotalNum()) ?></strong>
                      <?php endif; ?>
                  </p>
       
                  <div class="limiter">
                      <label><?php echo $this->__('Show') ?></label>
                      <select onchange="setLocation(this.value)">
                          <?php foreach ($this->getAvailableLimit() as  $_key=>$_limit): ?>
                              <option value="<?php echo $this->getLimitUrl($_key) ?>"<?php if($this->isLimitCurrent
      
      ($_key)): ?> selected="selected"<?php endif ?>>
                                  <?php echo $_limit ?>
                              </option>
                          <?php endforeach; ?>
                      </select><?php echo $this->__('per page') ?>
                  </div>
       
                  <?php echo $this->getPagerHtml() ?>
       
             </div>
       
              <?php if( $this->isExpanded() ): ?>
                  <div class="sorter">
                      <?php if( $this->isEnabledViewSwitcher() ): ?>
                          <p class="view-mode">
                              <?php $_modes = $this->getModes(); ?>
                              <?php if($_modes && count($_modes)>1): ?>
                                  <label><?php echo $this->__('View as') ?>:</label>
                                  <?php foreach ($this->getModes() as $_code=>$_label): ?>
                                      <?php if($this->isModeActive($_code)): ?>
                                          <strong title="<?php echo $_label ?>" class="<?php echo strtolower($_code); ?
      
      >">
                                          <?php echo $_label ?></strong> 
                                          <?php else: ?>
                                          <a href="<?php echo $this->getModeUrl($_code) ?>" title="<?php echo $_label 
      
      ?>" class="<?php echo strtolower($_code); ?>"><?php echo $_label ?> 
                                      <?php endif; ?>
                                  <?php endforeach; ?>
                              <?php endif; ?>
                          </p>
                      <?php endif; ?>
       
                      <div class="sort-by">
                          <label><?php echo $this->__('Sort By') ?></label>
                         <select onchange="setLocation(this.value)">
                              <?php foreach($this->getAvailableOrders() as $_key=>$_order): ?>
                                  <option value="<?php echo $this->getOrderUrl($_key, 'asc') ?>"<?php if($this-
      
      >isOrderCurrent($_key)): ?> selected="selected"<?php endif; ?>>
                                      <?php echo $this->__($_order) ?>
                                  </option>
                              <?php endforeach; ?>
                          </select>
                          <?php if($this->getCurrentDirection() == 'desc'): ?>
                              <a href="<?php echo $this->getOrderUrl(null, 'asc') ?>" title="<?php echo $this->__
      
      ('Set Ascending Direction') ?>"><img src="<?php echo $this->getSkinUrl('images/i_desc_arrow.gif') ?>" 
      
      alt="<?php echo $this->__('Set Ascending Direction') ?>" class="v-middle" /></a>
                          <?php else: ?>
                              <a href="<?php echo $this->getOrderUrl(null, 'desc') ?>" title="<?php echo $this->__
      
      ('Set Descending Direction') ?>"><img src="<?php echo $this->getSkinUrl('images/i_asc_arrow.gif') ?>" 
      
      alt="<?php echo $this->__('Set Descending Direction') ?>" class="v-middle" /></a>
       
                      <!--alwayly start-->
                              <label for="sale"><?php echo $this->__('On Sale') ?></label>
                              <input name="sale" id="sale" type="checkbox"
                                  value="<?php
                                      $currentUrl = Mage::helper('core/url')->getCurrentUrl();
                                      if($currentUrl===$helper->getOnSaleUrl()):
                                          echo $helper->getNotOnSaleUrl();
                                          echo "\"checked=\"checked";
                                      else:
                                          echo $helper->getOnSaleUrl();
                                      endif;
                                  ?>" autocomplete="off" onchange="setLocation(this.value)"/>
                      <!--alwayly end-->
                          <?php endif; ?>
                      </div>
                  </div>
              <?php endif; ?>
          </div>
      <?php endif ?>
      </strong>

      最后,创建我们的布局文件来让Magento来使用我们的toolbar.phtml。

      app/design/frontend/default/YOUR_THEME/layout/alwayly/onsale.xml

      
      <?xml version="1.0"?>
       
      <layout version="0.1.0">
          <catalog_category_default>
              <reference name="category.products">
                      <block type="inchoo_onsale/catalog_product_list" name="product_list" template="catalog/product/list.phtml">
                          <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="inchoo/onsale/toolbar.phtml">
                              <block type="page/html_pager" name="product_list_toolbar_pager"/>
       
                              <!-- The following code shows how to set your own pager increments -->
                              <!--
                                  <action method="setDefaultListPerPage"><limit>4</limit></action>
                                  <action method="setDefaultGridPerPage"><limit>9</limit></action>
                                  <action method="addPagerLimit"><mode>list</mode><limit>2</limit></action>
                                  <action method="addPagerLimit"><mode>list</mode><limit>4</limit></action>
                                  <action method="addPagerLimit"><mode>list</mode><limit>6</limit></action>
                                  <action method="addPagerLimit"><mode>list</mode><limit>8</limit></action>
                                  <action method="addPagerLimit" translate="label"><mode>list</mode><limit>all</limit><label>All</label></action>
                              -->
                          </block>
                          <action method="addColumnCountLayoutDepend"><layout>empty</layout><count>6</count></action>
                          <action method="addColumnCountLayoutDepend"><layout>one_column</layout><count>5</count></action>
                          <action method="addColumnCountLayoutDepend"><layout>two_columns_left</layout><count>4</count></action>
                          <action method="addColumnCountLayoutDepend"><layout>two_columns_right</layout><count>4</count></action>
                          <action method="addColumnCountLayoutDepend"><layout>three_columns</layout><count>3</count></action>
                          <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
                      </block>
              </reference>
          </catalog_category_default>
       
          <catalog_category_layered>
              <reference name="category.products">
                  <block type="inchoo_onsale/catalog_product_list" name="product_list" template="catalog/product/list.phtml">
                      <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="inchoo/onsale/toolbar.phtml">
                          <block type="page/html_pager" name="product_list_toolbar_pager"/>
       
                          <!-- The following code shows how to set your own pager increments -->
                          <!--
                              <action method="setDefaultListPerPage"><limit>4</limit></action>
                              <action method="setDefaultGridPerPage"><limit>9</limit></action>
                              <action method="addPagerLimit"><mode>list</mode><limit>2</limit></action>
                              <action method="addPagerLimit"><mode>list</mode><limit>4</limit></action>
                              <action method="addPagerLimit"><mode>list</mode><limit>6</limit></action>
                              <action method="addPagerLimit"><mode>list</mode><limit>8</limit></action>
                              <action method="addPagerLimit" translate="label"><mode>list</mode><limit>all</limit><label>All</label></action>
                          -->
                      </block>
                      <action method="addColumnCountLayoutDepend"><layout>empty</layout><count>6</count></action>
                      <action method="addColumnCountLayoutDepend"><layout>one_column</layout><count>5</count></action>
                      <action method="addColumnCountLayoutDepend"><layout>two_columns_left</layout><count>4</count></action>
                      <action method="addColumnCountLayoutDepend"><layout>two_columns_right</layout><count>4</count></action>
                      <action method="addColumnCountLayoutDepend"><layout>three_columns</layout><count>3</count></action>
                      <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
                  </block>
              </reference>
          </catalog_category_layered>
      </layout>
      

      看看效果:

      显示结果

      我们注意到分层导航和分页一样工作正常。如我们所期待的一样……

      ]]>
      Mon, 24 Aug 2015 13:46:52 +0000
      <![CDATA[magento中获取指定attribute属性的产品列表]]> https://www.360magento.com/blog/listing-products-by-attribute/ 获取自定义属性产品的列表

      这是一个向magento初学者一步一步展示magento如何按属性来列出产品排序的教程.
      我将以Magento已经创建好的新产品和促销产品功能开始.
      以下所有说明都是针对Magento1.9.0.0的

      列出带有属性New的产品列表

      在Magento后台管理面板,在Products management里面的Manage products 你能找到设置和定义新的属性。这篇教程中,我将使用名字叫Homepage的CMS Page来作为示例
      在CMS Page layout -> Layout Update XML里面已经被原有的cms page占据着:

      <reference name="content">
       
      <block type="core/template" name="home" as="home" template="page/home.phtml" >
       
      </block></reference>
      
      
      1. 首先,通过设置“Set Product as New from Date”和“Set Product as New to Date”来定义产品为新产品.
      2. Magento默认已经指定了新产品列表的模板,你可以在app/design/frontend/pro/YourTheme/template/catalog/product/new.phtml这个路径找到它.
      3. 在xml布局文件中通过block块结构体来定义你想要在哪里显示新产品模板(new.phtml).
      4. 插入新的block块
      <reference name="content">
       
      <block type="catalog/product_new" name="home.catalog.product.new" 	alias="product_new" as="newproducts"  	after="cms_page" template="catalog/product/new.phtml">
      <action method="setProductsCount"><count>8</count></action>
      <action method="setColumnCount"><count>4</count></action>
      </block>
       
      </reference>
      1. 指定你想要在哪展示带有新产品模板的块(在哪里调用这个block块)
        < ?php echo $this->getChildHtml('newproducts') ?>

        在我们的案例中,我们把Homepage模板定位于template/page/html/home.phtml

      2. 这就是所有你需要做的.

      注意:
      Content 是一个core/text_list类型 并且他可以支持嵌套所有的block类型.

      你可以设置你想要显示多少个产品在magento的前台:

      <action method="setProductsCount"><count>8</count></action>

      和多少列:

      <action method="setColumnCount"><count>4</count>4</action>

      列出所有带有Promotion属性的产品列表

      列出所有带有Promotion属性的产品列表方法在magento中已经存在,这与列出新产品稍微有点不同

      1. 首先我们需要在Magento后台为产品创建一个属性
      2. 创建一个名为“Promotion”的dropdown (Yes/No)类型的属性
      3. 如果你想为所有产品添加属性,那么需要将属性关联到default属性组
      4. 复制template/catalog/product/list.phtml文件到同级目录下,改名为promotion.phtml
      5. 在XML布局文件中定义block块的位置。在我们的案例中是CMS page下的“Homepage” 
        <block type="catalog/product_list_promotion" name="promotion" template="catalog/product/promotion.phtml" />
      6. 指定你想要在哪展示带有promotion.phtml模板的块在哪里调用这个block块)
        < ?php echo $this->getChildHtml('promotion') ?>

        在我们的案例中,我们把Homepage模板定位于template/page/html/home.phtml

      列出带有自定义模板和带有dropdown Yes/No类型属性的产品列表

      在这个案例中,我们将用magento的Promotion product方法来修改它.

      1. 创建新的目录文件app/code/local/Mage/Catalog/Block/Product/List/Example.php
      2. 复制app/code/core/Mage/Catalog/Block/Product/List/Promotion.php 并粘贴到Example.php
      3. 改变Example.php:

       

      class Mage_Catalog_Block_Product_List_Promotion extends Mage_Catalog_Block_Product_List

      到:

      class Mage_Catalog_Block_Product_List_Example extends Mage_Catalog_Block_Product_List

      也要改变:

      $collection->addAttributeToFilter('promotion', 1)

      到:

      $collection->addAttributeToFilter('example', 1)

      之后按照我之前写过Promotion属性的步骤执行。
      希望这篇教程能对你有所帮助。

      ]]>
      Sat, 22 Aug 2015 13:32:07 +0000
      <![CDATA[magento中通过邮件提醒客户下第一个订单]]> https://www.360magento.com/blog/remind-customers-place-order/

      在magento建设的网店中,有时客户创建账户后需要一些鼓励来拍下他们的第一个宝贝,这样的事情原因有很多,例如,你的客户忘记了你的网站的书签,因此他们想再次找到你的网站就很困难。在本文中我将介绍一个分厂好的方法,着眼于保持客户订单数量和给客户发送第一封订单邮件提醒,你可以用我们的免费插件来实现Alwayly_OrderReminder

      magento 订单提醒插件介绍

      至于Alwayly_OrderReminder插件的源码,可以去magento插件中心下载,这里我只通过一些代码介绍他的功能。Alwayly_OrderReminder插件的特点有:

      • 当客户注册之后,隔了数天还没有下单,这是可以通过这个magento插件发送邮件提醒客户下单
      • 可以配置发送邮件的最多数量,当发送最后一件邮件后可以采取一些措施(移动到不同的客户群或删除帐户)
      • 通过magento的事务性邮件模板功能可以配置定期的和最后一封邮件的模板
      • 配置magento订单提醒邮件的发送者,以及作为邮件副本或抄送发送给电子邮箱地址

      以下是配置选项提供的屏幕截图,z在你的magento后台System -> Configuration -> Sales Emails -> Order Reminders里面

      magento订单邮件提醒插件

      配置逻辑

      在本节中,我将介绍一些代码和在magento插件Alwayly_OrderReminder背后一些基本的逻辑

      Inchoo_OrderReminder_Model_Observer::processOrderReminders()方法是通过cron daily来出发,通过配置选项来处理客户,下面是config.xml文件的代码段用于此目的:

      <config>
          <crontab>
              <jobs>
                  <inchoo_orderreminder>
                      <!-- Daily at 1 am -->
                      <schedule><cron_expr>0 1 * * *</cron_expr></schedule>
                      <run><model>inchoo_orderreminder/observer::processOrderReminders</model></run>
                  </inchoo_orderreminder>
              </jobs>
          </crontab>
      </config>
      

      触发后

      下面是发送电子邮件的代码

      /**
       * Send transactional emails.
       * 
       * @param Varien_Object $customer Customer object
       * @param int $reminderLimit Number of days for last reminder
       * @param int $reminderKey Number of days since customer account was created
       * @param string $template Email template
       */
      protected function _sendOrderReminderEmail(Varien_Object $customer, $reminderLimit, $reminderKey, $template)
      {
          $this->_log('Preparing email...');
       
          // Get necessary vars
          $copyTo = $this->_getStoreConfigCopyTo();
          $copyMethod = $this->_getStoreConfigCopyMethod();
          $storeId = Mage::app()->getStore()->getId();
       
          // Uses code from Mage_Sales_Model_Order::sendNewOrderEmail()
          $mailer = Mage::getModel('core/email_template_mailer');
          $emailInfo = Mage::getModel('core/email_info');
          $emailInfo->addTo($customer->getEmail(), $customer->getName());
          if ($copyTo && $copyMethod == 'bcc') {
              // Add bcc to customer email
              foreach ($copyTo as $email) {
                  $emailInfo->addBcc($email);
       
                  $this->_log(sprintf('Add %s to Bcc.', $email));
              }
          }
          $mailer->addEmailInfo($emailInfo);
       
          // Email copies are sent as separated emails if their copy method is 'copy'
          if ($copyTo && $copyMethod == 'copy') {
              foreach ($copyTo as $email) {
                  $emailInfo = Mage::getModel('core/email_info');
                  $emailInfo->addTo($email);
                  $mailer->addEmailInfo($emailInfo);
       
                  $this->_log(sprintf('Will send a copy to  %s.', $email));
              }
          }
       
          // Set all required params and send emails
          $mailer->setSender($this->_getStoreConfigIdentity(), $storeId);
          $mailer->setStoreId($storeId);
          $mailer->setTemplateId($template);
          $mailer->setTemplateParams(
              array(
                  // Customer object
                  'customer' => $customer,
       
                  // Reminder for number of days
                  'reminder_days' => $reminderKey,
       
                  // Last reminder number of days
                  'reminder_limit' => $reminderLimit
              )
          );
       
          // Send
          $mailer->send();
       
          $this->_log('Email sent.');
      }
      

      接下来你可以学习下,也可以直接安装这个magento插件来达到你想要的效果

      ]]>
      Fri, 21 Aug 2015 16:58:18 +0000
      <![CDATA[如何创建magento下拉式的登陆框效果]]> https://www.360magento.com/blog/create-magento-dropdown-login/ magento在首页显示登陆注册框,创建magento下拉登陆框

      下拉式登录在大部分商店中并不常用,但在一些情况下它会是一个很有用的用户体验功能。 在这篇教程中,我将讲解在magento中如何在几分钟内创建这么一个下拉式登录框,让用户可以不用打开另外链接页面直接登陆。

      打开你的magento网站路径app/design/frontend/base/default/layout/customer.xml 并加入以下高亮代码

      <customer_logged_out>
      	<!---<reference name="right">
      		<block type="customer/form_login" name="customer_form_mini_login" before="-" template="customer/form/mini.login.phtml"/>
      	</reference>-->
      	<reference name="top.links">
      		<action method="addLink" translate="label title" module="customer"><label>Log In</label><url helper="customer/getLoginUrl"/><title>Log In</title><prepare/><urlParams/><position>100</position></action>
      		<block type="core/template" name="customer_form_mini_login" before="-" template="customer/form/mini.login.phtml"/>
      	</reference>
      	<remove name="reorder"></remove>
      </customer_logged_out>
      </pre>

      打开你的magento网站路径 app/design/frontend/base/default/template/page/template/links.phtml并添加一下高亮代码:

      <?php $_links = $this->getLinks(); ?>
      <?php if(count($_links)>0): ?>
      <ul class="links"<?php if($this->getName()): ?> id="<?php echo $this->getName() ?>"<?php endif;?>>
          <?php foreach($_links as $_link): ?>
              <?php if ($_link instanceof Mage_Core_Block_Abstract):?>
                  <?php echo $_link->toHtml() ?>
              <?php else: ?>
                  <ligetIsFirst()||$_link->getIsLast()): ?> class="getIsFirst()): ?>first<?php if($_link->getIsLast()): ?> last<?php endif; ?>"<?php endif; ?> <?php echo $_link->getLiParams() ?>><?php echo $_link->getBeforeText() ?><a href="<?php echo $_link->getUrl() ?>" title="<?php echo $_link->getTitle() ?>" <?php echo $_link->getAParams() ?>><?php echo $_link->getLabel() ?></a><?php echo $_link->getAfterText() ?>
                      <?php if($_link->getIsLast()): ?>
                          <?php echo $this->getChildHtml('customer_form_mini_login'); ?>
                      <?php endif; ?>
                  </li>
              <?php endif;?>
          <?php endforeach; ?>
      </ul>
      <?php endif; ?>
      

      最后打开你的magento网站路径app/design/frontend/base/default/template/customer/form/mini.login.phtml 同样的copy下面代码.

      <style>
      	#dropdown
      	{
      		position: absolute;
      		top: 70px;
      		right: 20px;
      		visibility: hidden;
      		float:right;
      	}
      	.last:hover #dropdown
      	{
      		visibility: visible;
      	}
      </style>
      <div class="block block-login" id="dropdown">
      	<div class="block-title">
      		<strong><span><?php echo $this->__('Login') ?></span></strong>
      	</div>
      	<form action="<?php echo $this->getUrl('customer/account/loginPost') ?>" method="post">
      		getBlockHtml('formkey'); ?>
      		<div class="block-content">
      			<label for="mini-login"><?php echo $this->__('Email:') ?></label><input type="text" name="login[username]" id="mini-login" class="input-text" />
      			<label for="mini-password"><?php echo $this->__('Password:') ?></label><input type="password" name="login[password]" id="mini-password" class="input-text" />
      			<div class="actions">
      				<button type="submit" class="button"><span><span><?php echo $this->__('Login') ?></span></button>
      			</div>
      		</div>
      	</form>
      </div>
      

      就是这样!当鼠标移到头部菜单“Log In”上时,你的magento网站顶部登录框就会出现。

      magento在首页显示登陆注册框,创建magento下拉登陆框

      这里值得记下的是:我们对Magento默认的mini登陆模板文件mini.login.phtml进行了一些修改让他在首页显示。

      我们也用core/template块代替了customer/form_login。这么做的原因是让页面标题“Customer login”能在所有页面显示。

      作为使用多个块的缺点,现在我们不能使用customer/form_login块中的方法。这就是我们使用$this->getUrl(‘customer/account/loginPost’)方法来替代$this->getPostActionUrl()的原因。

      你有一个形式存在的表关键字也是很重要的,否则你的表格将不会得到处理。

      <code><?php echo $this->getBlockHtml('formkey'); ?></code></pre>

      最好要说的就是让magento的前端开发者(也许就是你?)好好地利用下拉式登录。

      ]]>
      Fri, 21 Aug 2015 09:59:13 +0000
      <![CDATA[在magento的其他页面显示产品的星级评价]]> https://www.360magento.com/blog/display_product_rating/ 产品评论功能是Magento众多优秀特征之一。用好评论可以增加客户对你的品牌的信任,由此能显著增加你产品的销量。

      有时,你需要在评论页的其他页面展示评价星级。这正是我将要在这篇文章中写到的。

      下面这段代码适用于已经读取的产品(或者你知道产品的ID)——比如在购物车中调用产品评价星级;

      <?php
      $_product = $_item->getProduct(); //get the product in cart
      $storeId = Mage::app()->getStore()->getId();
      $summaryData = Mage::getModel('review/review_summary')
      					->setStoreId($storeId)
      					->load($_product->getId());
       
      if ($summaryData['rating_summary']):?>
      	<div class="ratings">
      		<div class="rating-box">
      			<div class="rating" style="width:<?php echo $summaryData['rating_summary'] ?>%"></div> 
      </div>
      </div>
      <?php endif; ?>

      如果我们访问购物车页面,我们会看到客户评价过的产品都会展示评价星级。

      在购物车中显示产品评价星级

      在$summaryData对象中,我们可以获取到这个数组的键值如下:

      //Entity id of a summary review
      ["primary_id"] => string(3) "100"
      //
      //Product id
      ["entity_pk_value"] => string(3) "119"
      //
      //Entity type id: 1-Product; 2-Customer; 3-Category
      ["entity_type"] => string(1) "1"
      //
      //Qty of reviews
      ["reviews_count"] => string(1) "2"
      //
      //Summarized rating: the percentage which represents number of stars, each 20% step fills up one star
      ["rating_summary"] => string(2) "80"
      //
      //Store id
      ["store_id"] => string(1) "1"
      

      记住展示评价星级的“Magento方式”是:创建一个block或者一个有接收product ID和store ID方法的helper,然后从视图文件中返回值。

      然而,你也可以将这段代码放入视图文件中来快速地为你的产品获取星级。

      注意,要在以上Html 标记(7-11行)之后输出星级的值,不然的话,星级将不会显示。

      ]]>
      Wed, 19 Aug 2015 15:20:23 +0000
      <![CDATA[magento中产品列表增加销量排序]]> https://www.360magento.com/blog/products-by-sold/ magento如何按产品销售量排序

      Magento默认提供了一些排序选项,例如:产品位置,名字,价格。在这篇文章中你将学会让产品按照销量来排序。

      要做到这些,我们需要重写一些Magento的核心文件。重定义核心文件并不是一个好的尝试,所以我们创建一个自己的模块来完成同样的功能并保证能升级。

      我假设你知道如何建立你自己的模块并创建对应的文件(app/etc/modules/Alwayly_Catalog.xml),所以Magento能识别我们的模块。

      现在,我们有了自己的模块并且已经被Magento识别,让我们创建自己的config.xml,路径为Alwayly/Catalog/etc/config.xml:

      <config>
          <modules>
              <Alwayly_Catalog>
                  <version>0.1.0</version>
              </Alwayly_Catalog>
          </modules>
          <global>
              <blocks>
                  <catalog>
                      <rewrite>
                          <product_list_toolbar>Alwayly_Catalog_Block_Product_List_Toolbar</product_list_toolbar>
                      </rewrite>
                  </catalog>
              </blocks>
              <models>
                  <catalog>
                     <rewrite>
                          <config>Alwayly_Catalog_Model_Config</config>
                      </rewrite>
                  </catalog>
                  <catalog_resource>
                      <rewrite>
                          <product_collection>Alwayly_Catalog_Model_Resource_Product_Collection</product_collection>
                      </rewrite>
                  </catalog_resource>
              </models>
          </global>
      </config>
      

      也许你会想到,我们将要重写以下三个文件:

      • Mage_Catalog_Block_Product_List_Toolbar
      • Mage_Catalog_Model_Config
      • Mage_Catalog_Model_Resource_Product_Collection

      我们的app/code/local/Alwayly_Catalog_Block_Product_List_Toolbar 应该这样:

      <?php
      class Alwayly_Catalog_Block_Product_List_Toolbar extends Mage_Catalog_Block_Product_List_Toolbar
      {
          public function setCollection($collection)
          {
              parent::setCollection($collection);
       
              if ($this->getCurrentOrder()) {
                  if($this->getCurrentOrder() == 'qty_ordered') {
                      $this->getCollection()->getSelect()
                           ->joinLeft(
                                  array('sfoi' => $collection->getResource()->getTable('sales/order_item')),
                                   'e.entity_id = sfoi.product_id',
                                   array('qty_ordered' => 'SUM(sfoi.qty_ordered)')
                               )
                           ->group('e.entity_id')
                           ->order('qty_ordered ' . $this->getCurrentDirection());
                  } else {
                      $this->getCollection()
                           ->setOrder($this->getCurrentOrder(), $this->getCurrentDirection())->getSelect();
                  }
              }
       
              return $this;
          }
      }
      

      我们继承了Mage_Catalog_Block_Product_List_Toolbar中所有的功能和方法但我们自己重写了setCollection()方法

      我们的Alwayly_Catalog_Model_Config是相当简单的:

      <?php
      class Alwayly_Catalog_Model_Config extends Mage_Catalog_Model_Config
      {
          public function getAttributeUsedForSortByArray()
          {
              return array_merge(
      			parent::getAttributeUsedForSortByArray(),
      			array('qty_ordered' => Mage::helper('catalog')->__('Sold quantity'))
      		);
          }
      }
      

      到了这一步,产品的排序应该已经奏效,但我们在分页上有点小问题,无法显示正确的数目。我们可以在 Alwayly/Catalog/Model/Resource/Product/Collection.php中用以下代码来修复这个问题。

      <?php
      class Alwayly_Catalog_Model_Resource_Product_Collection extends Mage_Catalog_Model_Resource_Product_Collection
      {
          protected function _getSelectCountSql($select = null, $resetLeftJoins = true)
          {
             $this->_renderFilters();
             $countSelect = (is_null($select)) ?
                 $this->_getClearSelect() :
                 $this->_buildClearSelect($select);
       
             if(count($countSelect->getPart(Zend_Db_Select::GROUP)) > 0) {
                 $countSelect->reset(Zend_Db_Select::GROUP);
             }
       
             $countSelect->columns('COUNT(DISTINCT e.entity_id)');
             if ($resetLeftJoins) {
                 $countSelect->resetJoinLeft();
             }
             return $countSelect;
          }
      }
      

      就是这样,在4个简单的步骤之后,我们的Magento网站中的商品就能按销量来排序了。 希望你乐在其中~~~

      ]]>
      Tue, 18 Aug 2015 13:05:46 +0000
      <![CDATA[用local.xml来重写或更新magento模板布局的xml结构]]> https://www.360magento.com/blog/magento-overwrite-xml/ magento使用local.xml来更新网站的布局

      在过去的5年magento管理代码的工作经验来看,在遵循magento的规则情况下,使用"local.xml"来重写或更新xml布局是最好的方法

      这篇文章是针对那些还不知道“local.xml”方法的。如果你已经在使用它,那恭喜你。如果没有,你绝对应该使用它。

      这个其实很简单:只使用一个文件时,就是local.xml,放置在你的主题文件夹layput下覆盖或更新主题所有设计的XML。

      优点:

      1. 仅仅只用一个文件就可以管理和更新magento主题的xml
      2. 没有必要去查找magento主题下的其他.xml文件,因为他是依赖于base文件夹下的xml
      3. 每次更改local.xml文件,是显而易见的,所以没有必要寻找内部的XML文件的变化

      缺点:

      1. 目前我还没发现,除非你不是想把代码更清晰明了,以后修改主题不是你的事情.

      如何使用local.xml文件.你需要做的就是创建一个插入你的主题文件夹里面并写入你的xml.由于magento是通过xmk文件读取的,所以它将首先搜索新创建的local.xml的变化并且重写和更新,然后再进入base文件夹里的.xml.

      如何设置local.xml:

      1. 在你的主题layout文件夹下创建local.xml文件 (app/frontend/default/your-theme/layout)
      2. 加入基本的xml标记结构

      <?xml version="1.0"?>
      <layout version="0.1.0"></layout>
      

      3. 将要重写的xml结构放入,看下面的例子:

      例子:

      1. 从这个区域删除/添加javascript:

      <!-- Let’s remove sleight js for IE7-->
      <reference name="head">
      <action method="removeItem"><type>js</type><name>lib/ds-sleight.js</name><params /><if>lt IE 7</if></action>
      </reference>
       
      <!-- Instead, add belated.js from your theme’s /js folder -->
      <action method="addItem"><type>skin_js</type><name>js/belated.js</name><params /><if>lt IE 7</if></action>
      

      2. 仅仅只为这个category page添加一个layout,设置一个模板并添加一些javascript.

      <catalog_product_view translate="label">
      <reference name="root">
      <action method="setTemplate">
      <template>page/1column.phtml</template>
      </action>
      </reference>
      <reference name="head">
      <action method="addItem"><type>skin_js</type>
      <name>js/stereotabs.js</name></action>
      <action method="addItem"><type>skin_js</type>
      <name>js/shadowbox/shadowbox.js</name></action>
      </reference>
      </catalog_product_view>
      

      3.从这个layput中移除指定的blocks(products compare, products viewed and related products) ,用 “remove”

      <default>
      <reference name="right">
      <remove name="catalog.compare.sidebar" />
      <remove name="left.reports.product.viewed" />
      <remove name="catalog.product.related" />
      </reference>
      
      

      4. 从这个layput中移除指定的blocks(products compare, products viewed and related products), 用 method=”unsetChild”

      <!-- Removed the Newsletter from the left sidebar -->
      <action method="unsetChild"><name>left.newsletter</name></action>
      <action method="unsetChild"><name>tags_popular</name></action>
      </reference>
      </default>
      

      当然local.xml有许多其他用途,但我这里只指出了添加,删除和更新模块,以更好地说明local.xml在开发流程的方式。

      希望这篇文章能给你的开发带来方便,谢谢阅读

      ]]>
      Mon, 17 Aug 2015 14:13:39 +0000
      <![CDATA[改变Magento Global Messages的显示方式]]> https://www.360magento.com/blog/fancy-magento-global-messages/ magento global message

      一般用magento开发的网站,客户很难看到或注意到一些提醒,也就是magento中的Global Messages

      我们可以通过把Global Messages放到页面的顶部来增强客户的浏览性,并通过动画来美化它

      我们可以通过下面的演示视频上的简单的三个步骤来看下我们要来达到的效果(Youtube视频,请翻墙观看)

      1. 创建local.xml插入到你自己的主题模板的layout下面,如果你已经有了这个文件,可以插入到这个文件里面适当的地方(阅读更多关于 “local.xml 方法”).

      <?xml version="1.0" encoding="UTF-8"?>
      <layout version="0.1.0">
          <default>
      		<reference name="root">
      			<remove name="global_messages" />
      		</reference>
      		<reference name="after_body_start">
      			<block type="core/template" name="alwayly_global_messages" template="core/alwayly_global_messages.phtml" before="-" />
      		</reference>
          </default>
      </layout>
      

      2. 创建alwayly_global_messages.phtml
      app/design/frontend/your_package/your_theme/template/core/

      <?php if($this->getMessagesBlock()->getMessageCollection()->count()): ?>
      	<div id="alwayly_global_messages" style="display: none">
      		<a href="javascript:void(0)" id="alwayly_global_messages_close" style="display: none" title="__('Hide messages') ?>">&times;</a>
      		<?php echo $this->getMessagesBlock()->getGroupedHtml(); ?>
      	</div>
      <?php $this->getMessagesBlock()->getMessageCollection()->clear(); ?>
       
      <script type="text/javascript">
      //<![CDATA[
      	Event.observe('alwayly_global_messages_close', 'click', function() {
      		Effect.SlideUp('alwayly_global_messages', { duration: 0.4, delay: 0.3 });
      		Effect.Fade('alwayly_global_messages_close', { duration: 0.2 });
      	});
      	Event.observe(document, 'dom:loaded', function() {
      		Effect.SlideDown('alwayly_global_messages', { duration: 0.4, delay: 0.3 });
      		Effect.Appear('alwayly_global_messages_close', { duration: 0.2, delay: 1 });
      	});
      //]]>
      </script>
      

      3. 在你的css文件里面追加#alwayly_global_messages的样式
      skin/frontend/your_ package/your_theme/css/

      #alwayly_global_messages {
      	position: relative;
      	z-index: 9999;
      }
      #alwayly_global_messages_close {
      	position: absolute;
      	top: 13px;
      	right: 13px;
      	z-index: 10000;
      	display: block;
      	width: 15px;
      	height: 15px;
      	background: #666;
      	text-align: center;
      	color: #fff;
      	font-size: 15px;
      	line-height: 15px;
      	text-decoration: none;
      	-webkit-border-radius: 15px;
      	-moz-border-radius: 15px;
      	border-radius: 15px;
      }
      

      你也可以根据你自己喜欢的样式来设计magento global messages的样式

      在video里面的例子,我已经添加了样式来覆盖原有的css

      .messages li, .messages li li { margin: 0 !important; }
      .error-msg, .success-msg, .note-msg, .notice-msg {
      	border: none !important;
      	font-size: 14px !important;
      	background-position: 13px 13px !important;
      	padding: 10px 35px !important;
      	min-height: 22px !important;
      }
      .note-msg, .notice-msg { color: #d6b501; }
      

      就这样了,你的客户可以看到一个醒目而好看的message了

      ]]>
      Mon, 17 Aug 2015 12:27:17 +0000
      <![CDATA[自定义magento导航菜单]]> https://www.360magento.com/blog/custom-category-menu-navigation/ magento的分类导航是top menu,但多数人用

      但有一些客户想要在magento的sidebar一个垂直的分类菜单导航,这样当客户在进入一个分类列表时就可以看到当前分类的统计分类

      在这篇文章中,我们将讨论建立一个完整的magento垂直菜单。我们将做3级深度的分类:类别,子类别和子类别。你可以再次基础上再扩展层级,但我相信对于大部分magento商店3级是绰绰有余。

      加载布局layout

      打开app/design/frontend/base/default/layout/page.xml或者是你自己主题下的layout文件。将下面的代码复制到default标签下面

      <reference name="right">
           <block type="core/template" name="catalog.sidenav" template="page/custom.phtml" before="cart_sidebar"/>
      </reference>
      

      这句代码的意思是告诉magento在把这个内容加载到我们每个页面的右边布局页面

      现在我们来创建magento模板文件

      创建菜单模板

      我们需要做的是通过所有的商店类别,得到他们的子类别(2级),子子类别(3级),并显示它们。在这个过程中,我们在list页面需要寻找一个与当前分类id相同的分类id。当我们找到它 - 我们将会做任何事情。

      创建app/design/frontend/base/default/template/page/custom.phtml 并复制下面代码

      <ul>
          <?php
              $obj = new Mage_Catalog_Block_Navigation();
              $storeCategories = $obj->getStoreCategories();
              Mage::registry('current_category') ? $currentCategoryId = Mage::registry('current_category')->getId() : $currentCategoryId='';
              foreach ($storeCategories as $_category):
          ?>
                  <li>
                      <strong><?php echo $_category->getName(); ?></strong>
                      <?php $categoryChildren = $_category->getChildren(); ?>
                      <?php if($categoryChildren->count()) : ?>
                          <ul>
       
                              <?php foreach($categoryChildren as $_categoryChild) : ?>
                                  <?php $_categoryChildModel = Mage::getModel('catalog/category')->load($_categoryChild->getId());?>
                                  <?php $categoryGrandchildren=$_categoryChild->getChildren(); ?>
                                  <li>
                                      <?php
                                          $currentCategoryId===$_categoryChild->getId() ? $bold="style=\"font-weight:bold\"" : $bold='';
                                          echo '&emsp;' . 'getUrl() . '"' . $bold . '>' .  $_categoryChild->getName() . '(' . $_categoryChildModel->getProductCollection()->count() . ')</a>';
                                      ?>
                                  </li>
                                  <?php if($categoryGrandchildren->count()) : ?>
                                      <?php foreach($categoryGrandchildren as $_categoryGrandchild) : ?>
                                          <?php $_categoryGrandchildModel = Mage::getModel('catalog/category')->load($_categoryGrandchild->getId());?>
                                          <li>
                                              <?php
                                                  $currentCategoryId===$_categoryChild->getId() ? $bold="style=\"font-weight:bold\"" : $bold='';
                                                  echo '&emsp;&emsp;' . 'getUrl() . '"' . $bold . '>' .  $_categoryGrandchild->getName() . '(' . $_categoryGrandchildModel->getProductCount() . ')</a>';
                                              ?>
                                          </li>
                                      <?php endforeach; ?>
                                  <?php endif; ?>
                              <?php endforeach; ?>
                          </ul>
                      <?php endif; ?>
                  </li>
              <?php endforeach ?>
      </ul>
      

      显示右边导航

      你应该能够看到你的页面的右边栏导航。这不正是最漂亮的菜单导航,但我相信你就可以改变风格,以满足您的需求。

      magento自定义分类导航

      你好可以插入这个模板文件到其他页面。例如在magento后台cms page中插入导航菜单

      {{block type="core/template" template="page/custom.phtml"}}
      
      ]]>
      Sun, 16 Aug 2015 12:58:46 +0000
      <![CDATA[magento获取Base Url , Skin Url , Media Url , Js Url , Store Url 和 Current Url]]> https://www.360magento.com/blog/magento-get-url/ magento如何在phtml文件中获取url?

      1. 获取 Base Url :

      Mage::getBaseUrl();

      2. 获取 Skin Url :

      Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_SKIN);

      (a) Unsecure Skin Url :

      $this->getSkinUrl('images/imagename.jpg');

      (b) Secure Skin Url :

      $this->getSkinUrl('images/imagename.gif', array('_secure'=>true));

      3. 获取 Media Url :

      Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA);

      4. 获取 Js Url :

      Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_JS);

      5. 获取 Store Url :

      Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);

      6. 获取 Current Url

      Mage::helper('core/url')->getCurrentUrl();

      magento如何在cms pages或static blocks中获取Url ?

      1. 获取 Base Url :

      {{store url=""}}

      2. 获取 Skin Url :

      {{skin url='images/imagename.jpg'}}

      3. 获取 Media Url :

      {{media url='imagename.jpg'}}

      4. 获取 Store Url :

      {{store url='mypage.html'}}
      ]]>
      Sat, 15 Aug 2015 12:53:30 +0000
      <![CDATA[magento在布局文件xml中如何添加/删除js和css]]> https://www.360magento.com/blog/add-js-css-in-xml/ 在magento中我们在head.phtml中调用css和js的代码是

      <?php echo $this->getCssJsHtml() ?>

      那么按照magento的规则,我们需要在layout中去加载css和js

      在magento如何通过xml加载外部js

      通畅我们会引用外部的css和js,比如google的字体,jquery库以及其他的库

       <!-- Add an EXTERNAL stylesheets  -->
      	  <action method="addLinkRel"><rel>stylesheet<href>https://fonts.googleapis.com/css?family=Roboto+Condensed:300italic,400,300,700|Open+Sans:300italic,400,300</href></action>
       
               <!--  Add an EXTERNAL javascript  -->
               <action method="addLinkRel"><rel>text/javascript<href>https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js</href></action>
      

      如何加载magento主题下的css,jss

      加载magento主题模板下面的css,js

       <!-- Add stylesheets from your local theme directory located in skin/frontend/ -->
                <action method="addCss"><stylesheet>css/styles.css</stylesheet></action>
       
               <!-- Add javascript from your local theme directory located in skin/frontend/ -->
                <action method="addItem">
      	          <type>skin_js<name>js/bootstrap.min.js
                </action>
      
      

      如何加载magento根目录js文件夹下的js文件

      <action method="addJs"><script>bootstrap.min.js</script></action>
      

      在magento中删除css和js

      在magento中的布局文件xml中删除js

      <action method="removeItem">
      <type>js</type>
      <name>calendar/calendar.js</name>
      </action>
      
      

      如何在phtm文件中删除js

      $this->getLayout->getBlock('head')->removeItem('js', 'calendar/calendar.js');
      
      ]]>
      Fri, 14 Aug 2015 13:03:05 +0000
      <![CDATA[magento中如何获取/判断用户登录状态]]> https://www.360magento.com/blog/get-customer-loggedin/ 大部分开发人员直接用

      Mage::getSingleton('customer/session')->isLoggedIn()

      来判断用户是否登录

      比如一般magento开发人员会这样用

      <?PHP
      
      //get customer login status ?>
      
      <?php $myStatus = Mage::getSingleton('customer/session')->isLoggedIn() ?>
      
      <?php if($myStatus): ?>
      
      <li><a href="/customer/account/index" title="Customer Register">My account</a> |</li>
      <li><?php echo $this->getLayout()->getBlock('header')->getWelcome() ?></li>
      
      <?php else: ?>
      
      <li><a href="/customer/account/index" title="Customer Register">My account</a></li>
      <li><a href="/customer/account/create" title="Customer Register">Register</a></li>
      
      <?php endif ?>

      但其实在magento里面用户登录状态判断函数早已封装好了.
      判断用户登陆状态是否登陆的原理是:Magento在Session中检查CustomerID是否已经设置,并且该CustomerID在数据库中是有效的。

      在app/code/core/Mage/Customer/Helper/Data.php文件中

      /**
           * Check customer is logged in
           *
           * @return bool
           */
          public function isLoggedIn()
          {
              return Mage::getSingleton('customer/session')->isLoggedIn();
          }

      在app/code/core/Mage/Customer/Model/Session.php文件中

      /**
           * Checking customer login status
           *
           * @return bool
           */
          public function isLoggedIn()
          {
              return (bool)$this->getId() && (bool)$this->checkCustomerId($this->getId());
          }
      

      所以我们可以在全局用

       if ($this->helper('customer')->isLoggedIn()) { 
        // is logon 
       } 
      

      在magento中判断用户的登录状态或是否登录

      ]]>
      Thu, 13 Aug 2015 13:49:16 +0000
      <![CDATA[magento通过sql删除magento产品数据]]> https://www.360magento.com/blog/delete-all-products-with-sql/ 删除magento所有数据最快的方法是直接使用SQL查询。记得把SET FOREIGN_KEY_CHECKS=0;放在开始,把SET FOREIGN_KEY_CHECKS=1;放最后。

      删除magento所有产品数据

      复制下面代码到phpmyadmin中的SQL查询执行

      
      TRUNCATE TABLE `catalog_product_bundle_option`;
      TRUNCATE TABLE `catalog_product_bundle_option_value`;
      TRUNCATE TABLE `catalog_product_bundle_selection`;
      TRUNCATE TABLE `catalog_product_entity_datetime`;
      TRUNCATE TABLE `catalog_product_entity_decimal`;
      TRUNCATE TABLE `catalog_product_entity_gallery`;
      TRUNCATE TABLE `catalog_product_entity_int`;
      TRUNCATE TABLE `catalog_product_entity_media_gallery`;
      TRUNCATE TABLE `catalog_product_entity_media_gallery_value`;
      TRUNCATE TABLE `catalog_product_entity_text`;
      TRUNCATE TABLE `catalog_product_entity_tier_price`;
      TRUNCATE TABLE `catalog_product_entity_varchar`;
      TRUNCATE TABLE `catalog_product_link`;
      TRUNCATE TABLE `catalog_product_link_attribute`;
      TRUNCATE TABLE `catalog_product_link_attribute_decimal`;
      TRUNCATE TABLE `catalog_product_link_attribute_int`;
      TRUNCATE TABLE `catalog_product_link_attribute_varchar`;
      TRUNCATE TABLE `catalog_product_link_type`;
      TRUNCATE TABLE `catalog_product_option`;
      TRUNCATE TABLE `catalog_product_option_price`;
      TRUNCATE TABLE `catalog_product_option_title`;
      TRUNCATE TABLE `catalog_product_option_type_price`;
      TRUNCATE TABLE `catalog_product_option_type_title`;
      TRUNCATE TABLE `catalog_product_option_type_value`;
      TRUNCATE TABLE `catalog_product_super_attribute_label`;
      TRUNCATE TABLE `catalog_product_super_attribute_pricing`;
      TRUNCATE TABLE `catalog_product_super_attribute`;
      TRUNCATE TABLE `catalog_product_super_link`;
      TRUNCATE TABLE `catalog_product_enabled_index`;
      TRUNCATE TABLE `catalog_product_website`;
      TRUNCATE TABLE `catalog_category_product_index`;
      TRUNCATE TABLE `catalog_category_product`;
      TRUNCATE TABLE `cataloginventory_stock_item`;
      TRUNCATE TABLE `cataloginventory_stock_status`;
      TRUNCATE TABLE `cataloginventory_stock`;
      TRUNCATE TABLE `rating_option_vote`; 
      TRUNCATE TABLE `rating_option_vote_aggregated`;
      TRUNCATE TABLE `review`; 
      TRUNCATE TABLE `review_detail`; 
      TRUNCATE TABLE `review_entity_summary`; 
      TRUNCATE TABLE `review_store`;
      INSERT  INTO `catalog_product_link_type`(`link_type_id`,`code`) VALUES (1,'relation'),(2,'bundle'),(3,'super'),(4,'up_sell'),(5,'cross_sell');
      INSERT  INTO `catalog_product_link_attribute`(`product_link_attribute_id`,`link_type_id`,`product_link_attribute_code`,`data_type`) VALUES (1,2,'qty','decimal'),(2,1,'position','int'),(3,4,'position','int'),(4,5,'position','int'),(6,1,'qty','decimal'),(7,3,'position','int'),(8,3,'qty','decimal');
      INSERT  INTO `cataloginventory_stock`(`stock_id`,`stock_name`) VALUES (1,'Default');
      TRUNCATE TABLE `catalog_product_entity`;
      
      

      删除magento所有分类

      复制下面代码到phpmyadmin中的SQL查询执行

      TRUNCATE TABLE `catalog_category_entity`;
      TRUNCATE TABLE `catalog_category_entity_datetime`;
      TRUNCATE TABLE `catalog_category_entity_decimal`;
      TRUNCATE TABLE `catalog_category_entity_int`;
      TRUNCATE TABLE `catalog_category_entity_text`;
      TRUNCATE TABLE `catalog_category_entity_varchar`;
      TRUNCATE TABLE `catalog_category_product`;
      TRUNCATE TABLE `catalog_category_product_index`;
      
      INSERT  INTO `catalog_category_entity`(`entity_id`,`entity_type_id`,`attribute_set_id`,`parent_id`,`created_at`,`updated_at`,`path`,`POSITION`,`level`,`children_count`) VALUES (1,3,0,0,'0000-00-00 00:00:00','2009-02-20 00:25:34','1',1,0,1),(2,3,3,0,'2009-02-20 00:25:34','2009-02-20 00:25:34','1/2',1,1,0);
      INSERT  INTO `catalog_category_entity_int`(`value_id`,`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`) VALUES (1,3,32,0,2,1),(2,3,32,1,2,1);
      INSERT  INTO `catalog_category_entity_varchar`(`value_id`,`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`) VALUES (1,3,31,0,1,'Root Catalog'),(2,3,33,0,1,'root-catalog'),(3,3,31,0,2,'Default Category'),(4,3,39,0,2,'PRODUCTS'),(5,3,33,0,2,'default-category');
      
      /**** Magento ver. 1.6.x.x ****/
      
      TRUNCATE TABLE `catalog_category_entity`;
      TRUNCATE TABLE `catalog_category_entity_datetime`;
      TRUNCATE TABLE `catalog_category_entity_decimal`;
      TRUNCATE TABLE `catalog_category_entity_int`;
      TRUNCATE TABLE `catalog_category_entity_text`;
      TRUNCATE TABLE `catalog_category_entity_varchar`;
      TRUNCATE TABLE `catalog_category_product`;
      TRUNCATE TABLE `catalog_category_product_index`;
      
      INSERT  INTO `catalog_category_entity`(`entity_id`,`entity_type_id`,`attribute_set_id`,`parent_id`,`created_at`,`updated_at`,`path`,`POSITION`,`level`,`children_count`) VALUES (1,3,0,0,'0000-00-00 00:00:00','0000-00-00 00:00:00','1',1,0,1), (2,3,3,1,'0000-00-00 00:00:00','0000-00-00 00:00:00','1/2','1','1','0');
      INSERT  INTO `catalog_category_entity_int`(`value_id`,`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`) VALUES (1,3,32,0,2,1),(2,3,36,0,2,1),(3,3,61,0,2,1),(4,3,44,0,2,NULL),(5,3,45,0,2,1),(6,3,62,0,2,1),(7,3,63,0,2,1),(8,3,64,0,2,NULL);
      INSERT  INTO `catalog_category_entity_varchar`(`value_id`,`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`) VALUES (1,3,31,0,1,'Root Catalog'),(2,3,35,0,2,'Default Category'),(3,3,37,0,2,'default-category'),(4,3,40,0,2,NULL),(5,3,43,0,2,'PRODUCTS'),(6,3,52,0,2,NULL),(7,3,55,0,2,NULL);
      

      删除magento所有订单数据

      复制下面代码到phpmyadmin中的SQL查询执行

      
      TRUNCATE `sales_order`;
        TRUNCATE `sales_order_datetime`;
        TRUNCATE `sales_order_decimal`;
        TRUNCATE `sales_order_entity`;
        TRUNCATE `sales_order_entity_datetime`;
        TRUNCATE `sales_order_entity_decimal`;
        TRUNCATE `sales_order_entity_int`;
        TRUNCATE `sales_order_entity_text`;
        TRUNCATE `sales_order_entity_varchar`;
        TRUNCATE `sales_order_int`;
        TRUNCATE `sales_order_text`;
        TRUNCATE `sales_order_varchar`;
        TRUNCATE `sales_flat_quote`;
        TRUNCATE `sales_flat_quote_address`;
        TRUNCATE `sales_flat_quote_address_item`;
        TRUNCATE `sales_flat_quote_item`;
        TRUNCATE `sales_flat_quote_item_option`;
        TRUNCATE `sales_flat_order_item`;
        TRUNCATE `sendfriend_log`;
        TRUNCATE `tag`;
        TRUNCATE `tag_relation`;
        TRUNCATE `tag_summary`;
        TRUNCATE `wishlist`;
        TRUNCATE `log_quote`;
        TRUNCATE `report_event`;
      
        ALTER TABLE `sales_order` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_datetime` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_decimal` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_entity` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_entity_datetime` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_entity_decimal` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_entity_int` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_entity_text` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_entity_varchar` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_int` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_text` AUTO_INCREMENT=1;
        ALTER TABLE `sales_order_varchar` AUTO_INCREMENT=1;
        ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
        ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
        ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
        ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
        ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
        ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
        ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
        ALTER TABLE `tag` AUTO_INCREMENT=1;
        ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
        ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
        ALTER TABLE `wishlist` AUTO_INCREMENT=1;
        ALTER TABLE `log_quote` AUTO_INCREMENT=1;
        ALTER TABLE `report_event` AUTO_INCREMENT=1;
      

      删除magento所有客户数据

      复制下面代码到phpmyadmin中的SQL查询执行

      
      TRUNCATE `customer_address_entity`;
        TRUNCATE `customer_address_entity_datetime`;
        TRUNCATE `customer_address_entity_decimal`;
        TRUNCATE `customer_address_entity_int`;
        TRUNCATE `customer_address_entity_text`;
        TRUNCATE `customer_address_entity_varchar`;
        TRUNCATE `customer_entity`;
        TRUNCATE `customer_entity_datetime`;
        TRUNCATE `customer_entity_decimal`;
        TRUNCATE `customer_entity_int`;
        TRUNCATE `customer_entity_text`;
        TRUNCATE `customer_entity_varchar`;
        TRUNCATE `log_customer`;
        TRUNCATE `log_visitor`;
        TRUNCATE `log_visitor_info`;
      
        ALTER TABLE `customer_address_entity` AUTO_INCREMENT=1;
        ALTER TABLE `customer_address_entity_datetime` AUTO_INCREMENT=1;
        ALTER TABLE `customer_address_entity_decimal` AUTO_INCREMENT=1;
        ALTER TABLE `customer_address_entity_int` AUTO_INCREMENT=1;
        ALTER TABLE `customer_address_entity_text` AUTO_INCREMENT=1;
        ALTER TABLE `customer_address_entity_varchar` AUTO_INCREMENT=1;
        ALTER TABLE `customer_entity` AUTO_INCREMENT=1;
        ALTER TABLE `customer_entity_datetime` AUTO_INCREMENT=1;
        ALTER TABLE `customer_entity_decimal` AUTO_INCREMENT=1;
        ALTER TABLE `customer_entity_int` AUTO_INCREMENT=1;
        ALTER TABLE `customer_entity_text` AUTO_INCREMENT=1;
        ALTER TABLE `customer_entity_varchar` AUTO_INCREMENT=1;
        ALTER TABLE `log_customer` AUTO_INCREMENT=1;
        ALTER TABLE `log_visitor` AUTO_INCREMENT=1;
        ALTER TABLE `log_visitor_info` AUTO_INCREMENT=1;
      
        -- Now, lets Reset all ID counters
        TRUNCATE `eav_entity_store`;
        ALTER TABLE  `eav_entity_store` AUTO_INCREMENT=1;
      

      删除产品图片,清空

      media/catalog/product

      目录

      通过写php脚本删除产品数据

      Step 1. 创建skus.csv文件

      从magento后台导出所有产品的sku,导出文件为skus.csv

      Step 2. 创建php脚本文件delete-data.php

      在你的网站根目录创建一个php文件delete-data.php,然后复制以下代码

      require_once '../app/Mage.php';
      Mage :: app("default") -> setCurrentStore( Mage_Core_Model_App :: ADMIN_STORE_ID );
      $skuAll =array();
      $file_handle = fopen("skus.csv", "r");
       while (!feof($file_handle) ) {
          $line_of_text = fgetcsv($file_handle, 1024);
      $allSku = $line_of_text[0];
      
      }
      $products = Mage::getResourceModel('catalog/product_collection')
          ->addAttributeToSelect('*') 
          ->addAttributeToFilter(
              'sku', array('in' => $allSku)
          )
          ->load();
      
          if(is_array($products))
          {
              foreach ($products as $key => $pId)
              {
                  try
                  {
                      $product = Mage::getModel('catalog/product')->load($pId)->delete();
                      echo "successfully deleted product with ID: ". $pId ."
      "; } catch (Exception $e) { echo "Could not delete product with ID: ". $pId ."
      "; } } }
      ]]>
      Thu, 13 Aug 2015 13:17:07 +0000
      <![CDATA[magento获取所有分类列表]]> https://www.360magento.com/blog/get-all-category-listing-in-magento/ 有的时候我们要显示网页所有类别或Magento的任何CMS页面。有许多不同的方式来获得的类别列表。我会告诉你如何得到所有类别您的Magento店的名单。

      1.显示所有的Magento分类列表(Active/Inactive)

      下面的代码将获取在你的magento商店里面的所有分类:

      $categories = Mage::getModel('catalog/category')->getCollection()->addAttributeToSelect('*');
      

      2. 显示所有激活的分类( Active Categories)

      下面的代码将获取你的magento商店里的所有激活的分类,过滤掉没有激活的分类

      $categories = Mage::getModel('catalog/category') ->getCollection() ->addAttributeToSelect('*') ->addIsActiveFilter(); 
      

      3. 在magento中显示任意级别的并且是激活状态下的分类

      下面代码将获取所有特定级别的激活分类,在这里我选择了一级分类,并按照分类的name排序

      $categories = Mage::getModel('catalog/category') ->getCollection() ->addAttributeToSelect('*') ->addIsActiveFilter() ->addLevelFilter(1) ->addOrderField('name'); 
      

      4. 在magento中显示特定分类存储类型

      下面的代码将获取所有激活的的存储特定分类

      getStoreCategories($sorted=false, $asCollection=false, $toLoad=true) 
      $helper = Mage::helper('catalog/category'); 
      
      // sorted by name, fetched as collection 
      $categoriesCollection = $helper->getStoreCategories('name', true, false); 
      
      // sorted by name, fetched as array 
      $categoriesArray = $helper->getStoreCategories('name', false, false);

      5. 在magento中只显示顶级分类

      下面的代码将获取所有magento顶级分类

      <?php $_helper = Mage::helper('catalog/category') ?> 
      <?php $_categories = $_helper->getStoreCategories() ?> 
      <?php if (count($_categories) > 0): ?> 
      <ul> 
      <?php foreach($_categories as $_category): ?> 
      <li> 
      <a href="getCategoryUrl($_category) ?>"> 
      <?php echo $_category->getName() ?> 
      </a> 
      </li> 
      <?php endforeach; ?> 
      </ul> 
      <?php endif; ?> 
      

      6. 在magento中显示所有顶级分类及其所有子分类

      下面的代码将获取所有的magento商店中顶级分类以及所有子分类

      <?php $_helper = Mage::helper('catalog/category') ?>
      <?php $_categories = $_helper->getStoreCategories() ?>
      <?php $currentCategory = Mage::registry('current_category') ?>
      <?php if (count($_categories) > 0): ?>
      <ul>
      <?php foreach($_categories as $_category): ?>
      <li>
      <a href="<?php echo $_helper->getCategoryUrl($_category) ?>">
      <?php echo $_category->getName() ?> //Top Level Category Listing
      </a>
      <?php $_category = Mage::getModel('catalog/category')->load($_category->getId()) ?>
      <?php $_subcategories = $_category->getChildrenCategories() ?>
      <?php if (count($_subcategories) > 0): ?>
      <ul>
      <?php foreach($_subcategories as $_subcategory): ?>
      <li>
      <a href="<?php echo $_helper->getCategoryUrl($_subcategory) ?>"> //Sub Category Listing
      <?php echo $_subcategory->getName() ?>
      </a>
      </li>
      <?php endforeach; ?>
      </ul>
      <?php endif; ?>
      </li>
      <?php endforeach; ?>
      </ul>
      <?php endif; ?>
      

      7. 在magento中显示当前顶级分类的子分类

      下面的代码将获取当前顶级分类的所有子分类

      <?php $_currentCategory = Mage::register('current_category') ?>
      <?php $_helper = Mage::helper('catalog/category') ?>
      <?php $_categories = $_helper->getStoreCategories() ?>
      <?php if (count($_categories) > 0): ?>
      <ul>
      <?php foreach($_categories as $_category): ?>
      <li>
      <a href="<?php echo $_helper->getCategoryUrl($_category) ?>" title="<?php echo $_category->getName() ?>">
      <?php echo $_category->getName() ?>
      </a>
      <?php if ($_category->getId() == $_currentCategory->getId()): ?>
      <?php $_subcategories = $_currentCategories->getChildrenCategories() ?>
      <?php if (count($_subcategories) > 0): ?>
      <ul>
      <?php foreach($_subcategories as $_subcategory): ?>
      <li>
      <a href="<?php echo $_helper->getCategoryUrl($_subcategory) ?>" title="<?php echo $_subcategory->getName() ?>">
      <?php echo $_subcategory->getName() ?>
      </a>
      </li>
      <?php endforeach; ?>
      </ul>
      <?php endif; ?>
      <?php endif; ?>
      </li>
      <?php endforeach; ?>
      </ul>
      <?php endif; ?>
      

      希望对你有帮助,Thanks

      ]]>
      Wed, 12 Aug 2015 09:43:43 +0000
      <![CDATA[论中国支付网关]]> https://www.360magento.com/blog/chinese-payment-gateways/ magento中国支付网关

      在中国的网络市场,贝宝几乎不见踪影(它主要被用于帮助中国商人向国外出口) ,因此,在中国需要依靠中国现有的主要支付网关:支付宝、财付通、中国银联等。

      同时,通过信用卡支付的方式在中国市场也几乎不存在:中国的终端用户并不热衷于在电子商务网站上输入自己的信用卡信息。在他们的眼里,允许终端用户输入自己的信用卡信息看起来非常可疑,因此不建议在中国使用。

      从终端用户的角度分析,最流行的支付网关具有以下优点:

      1 )允许帐户充值和在线支付

      终端用户可以支付的金额为目前其支付网关帐户内的最高金额。这意味着,如果欲购买的产品高出其帐户余额,便无法完成付款。

      另外,在中国,用户使用某种支付方式时对一次性支付的总额有一定限制,这一点非常重要。

      2 )使用支付网关后被转向到银行页面

      在这种情况下,终端用户将被转向到他们的银行来完成支付,支付方式在此作为连通其银行账户页面的桥梁。

      主要的支付网关都能访问大多数中国的银行。

      对于中国的终端用户,这种付款方式尽管在付款流程优化方面不是很有效率,也同样非常受欢迎。

      3 )快捷支付:支付网关直接链接到银行帐户

      快捷支付对于中国的终端用户是一个非常新颖的支付系统。它于2011年年底通过支付宝的快捷支付功能,在市场上首次亮相。

      这种支付网关简化了支付过程,因为终端用户在注册支付网关的过程中已将其银行账户链接到该支付网关。随后,购买金额会从他的相应银行帐户中自动扣除。

      支付宝、财付通和银联已经提供这种类型的支付方式。

      如何选择支付网关呢?

      如果您不知道该为您的电子商务网站选择哪种支付网关,你需要重视的第一点便是它们的受欢迎程度:

      - 支付宝:市场占有率45%

      - 财付通:市场占有率21%

      - 银联:市场占有率11%

      支付宝显然是最流行的支付网关系统,因为淘宝和天猫只使用这种支付网关。

      另一个要考虑的标准是每个支付网关收取与交易量相应的佣金。在中国将遇到的难题是,这里并不采取固定的佣金率。因此,作为电商,您将不得不根据你的交易水平与付款网关供应商直接谈判。

      由于与任何中国的支付网关供应商打交道都需要繁琐的行政工作,我们的客户通常在中国只采用一种在线付款方式。

      ]]>
      Wed, 12 Aug 2015 09:13:22 +0000
      <![CDATA[如何安装Magento 2.0]]> https://www.360magento.com/blog/install-magento2/ 2014年12月的Magento的2.0测试版发布。我是如此渴望得到它,因为“Magento2将标志着一个转折点,并会扩大其市场占有率上!”(马克拉维尔,在eBay担任产品副总裁、中型市场和Magento总经理)。 Wow, sound great!


      在等待公测版本中,我们应该抓紧时间,并开始有一个alpha版,我认为它的安装步骤,不会有太大变化。该指南是有点长,但它肯定是值得你花时间阅读:)

       

      在本地安装magento2

      1. 安装 xampp

      进入这里安装

      编辑文件: php.ini 开启以下扩展:

      ;extension=php_openssl.dll  ⇒  extension=php_openssl.dll
      ;extension=php_intl.dll        ⇒  extension=php_intl.dll

      2. 安装 composer:

      通过这个链接安装 composer

      下载 Composer-Setup.exe 并在本地安装

      运行文件Composer-Setup.exe

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装

      ⇒ 选择 Next继续

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第2步

      ⇒ 选择 Next继续

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第3步

      选择php.exe安装在xampp的路径是 C:\xampp\php\php.exe 并点击 Next

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第4步

      ⇒ 选择Install

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第5步

      接下来, 等待一会儿.

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第6步

      如果发生错误, 你看一样 任务管理器选择关闭Window Explorer。 选择Retry to continue.

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第7步

      这个composer 安装进程将会出现下面窗口表示结束 :

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第8步

      再次运行 Window Explorer:

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第9步

      3. Install Magento 2.0

      在这篇文章中,我使用的Magento2.0代码是来自 https://github.com/magento/magento2

      复制magento2源码到 htdocs 本地文件夹. 然后, 右键并选择 Composer Installation在这个文件上 \setup\composer.json

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第10步

      显示cmd界面,你要等待一会儿

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第11步

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第12步

      登录到 mysql的管理面板phpmyadmin 来创建database

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第13步

      在浏览器运行链接: localhost/magento20/ 开始安装 Magento 2.0

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第14步

      接下来就是一步步进行安装magento 2.0:

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第15步

      Step 1: 检查服务器环境

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第16步

      当Readiness Check 步骤完成后, 选择 Next

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第17步

      在step 2填写服务器信息和数据库信息. 然后点击 Next继续

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第18步

      Step 3: 提供你的网站访问链接并继续

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第19步

      step 4: 自定义你的商店. 在进行step 5之前你可以编辑你的time zone, currency 和 language.

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第20步

      Step 5需要你 创建管理员账号. 填入信息, 知道最后一项

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第21步

      选择Install. 在 step 6, 你将看到以下屏幕

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第22步

      这将需要一些时间才能完成安装. 所有的完成之后,窗口将显示为

      Magento 2.0 - 如何安装magento 2.0 - Composer 设置安装第23步

      在线上服务器安装 Magento 2.0

      1. copy源代码到服务器

      2. 运行 puty来安装 composer

      i. 移动到安装文件

      Cd folder_magento/setup

      ii. 下载 composer

      curl -sS https://getcomposer.org/installer | php

      iii. Run composer

      php composer.phar install

      3. 运行magento链接地址安装,和在本地安装一样的.

      ]]>
      Tue, 11 Aug 2015 08:23:35 +0000
      <![CDATA[magento网站seo优化之Magento高级优化]]> https://www.360magento.com/blog/optimize-your-magento-website03/ 3. 高级的Magento SEO 和相同的内容

      完成了所有基础的设置后,剩下的事情就是一件简单的事:相同的内容。实际上是大量的相同的内容。商品里有相同的内容,至少,在下面的URLs有完全相同的内容:

      www.360magento.com/product.html

      www.360magento.com/category1/product.html

      www.360magento.com/catalog/product/view/id/1/

      www.360magento.com/catalog/product/view/id/1/category/1/
      此外,商品回顾页面有几乎一样的内容。另一个问题是目录,你有大量相同的内容在层级导航中和索引选择中。最坏的情况是一个商品在这个页面显示之外,至少还会在这个页面以外的4个页面中显示。
      我们将要去掉这些相同的内容,并允许它们被蜘蛛爬但不被索引,固定目录的索引选择和层级导航。
      3.1. 无内容页面需设置成Noindex, follow
      安装 Yoast robots meta module 可确保设置成防止索引所有的无内容页面,如下:

      现在搜索引擎将通过所有的链接来到这些页面上但不会再索引中显示这些页面。

      3.2. Nofollowing 非必需的链接

      另一简单的步骤来提高你的 Magento SEO 是停止链接到你的登录,付款,希望购买列表和所有其他没有内容的页面。对于RSS feeds,层级导航,增加商品到希望购买列表,增加商品到比较列表来说也是同样的设置。目前还没有插件来完成这些工作。你不得不进入你的模板文件中手工完成。

      3.3. 规范的URLs

      帮助搜索引擎理解你页面中的相同内容,你可以在每个页面使用你更喜欢的URL,使用新的 canonical URL tag (规范的URL标签),你可以安装这个 Canonical URL’s for Magento 模块完成。

      3.4. XML 地图

      XML 地图是让搜索引擎知道你的内容在哪里的简单方法,它不会帮助你提高排名,但它可以帮助你更快得到索引。你可以手工建立一个XML地图,后台点击 Catalog => Google Sitemap => Add Sitemap, 选择一个文件名,路径和商店界面,然后点击 “Save & Generate”。

      然后你可以简单的把下面的代码放到你的 robots.txt 文件中指引搜索引擎向你的 sitemap.xml 文件:

      # Website Sitemap
      Sitemap: http://www.360magento.com/sitemap.xml

      ]]>
      Sat, 08 Aug 2015 11:27:03 +0000
      <![CDATA[magento网站seo优化之Magento模板优化]]> https://www.360magento.com/blog/optimize-your-magento-website02/ 2.Magento模板优化

      2.1. 优化了的空白模板

      默认的Magento皮肤如 “Default Theme”, “Blue Skin” 和 “Modern Theme” 在标题方面的工作做得不好,从SEO的角度来看,有很多的地方可以改进。为使它对你变得简单,这里有一款空白的Magento SEO模板,基于Magento的核心技术,空白模板合并了所有的东西,你可以在这里下载.

      2.2. 标题

      默认的 logo 是一个 h1标签, 应该只是出现在首页,在别的页面上它应该是一个h3标签. 最重要的事实让标题的内容置于 h1 标签之中,例如,在目录页它应是目录名在商品也应是商品名。

      下一步是清除过量的标题。一个好主意是清除侧栏的标题,或者做一个和商店相关的文字(包括关键字)。在h4标签中增加关键字到标题往往对seo 是不利的. 你可以把所有标题的 h4 标签换成 div ,在div中添加 strong 标签更好。接着优化你的内容,在目录页中把商品名放在 h3 里,把目录名放在 h1里。在商品页,你应该把商品名放在h1里.

      2.3. 优化你的代码

      保持你的模板清爽,把你的模板文件中的所有 javascript 和 CSS 移到外部的 javascripts 和css 文件中,因为它们对你的Magento SEO没有任何好处。这样做可以确保你的用户在首次读取文件的时候储存那些文件,搜索引擎不需要花费大量的时间来下载它们。

      2.4. 提升magento访问速度

      一个很重要的情况是搜索引擎每一天要在你的商店爬过多少页面,你的商店的读取速度有多快。

      你可以做两件事来增加你的Magento的速度:

      激活缓存。后台点击 System => Cache Management => enable all caching features (勾选复选框).

      一个域名的主机和服务器的设置也是很重要的。用 MySQL 和 PHP opcode 缓存你可以提高你的Mageto速度。

      另一件需要考虑的就是减少外部文件的数量。每一个你让人们下载的文件,他们的浏览器会建立另一个连接到网络服务器。所以非常好的主意就是减少外部文件的数量,合并几个文件为一个文件。默认的Magento已经合并了几乎所有的 javascript 文件到一个文件中。

      但 stylesheets 文件没有合并:默认模板有6个不同的stylesheet 文件。你可以把这些文件合并成一个新文件,除了print.css文件,或者你可以安装这个扩展 Fooman Speedster module. 除了合并文件外,这个模块能压缩和缓存你的 javascript 和 stylesheet 文件。 (请注意Speedster的使用条件: mod_rewrite 必须可用,你的服务器需要支持.htaccess。 如果你在Magento同时使用规范的URLs和 Fooman Speedster,你需要利用this download 重写Canonical module 。)

      3. 高级的Magento SEO 和相同的内容

      完成了所有基础的设置后,剩下的事情就是一件简单的事:相同的内容。实际上是大量的相同的内容。商品里有相同的内容,至少,在下面的URLs有完全相同的内容:

      www.360magento.com/product.html

      www.360magento.com/category1/product.html

      www.360magento.com/catalog/product/view/id/1/

      www.360magento.com/catalog/product/view/id/1/category/1/
      此外,商品回顾页面有几乎一样的内容。另一个问题是目录,你有大量相同的内容在层级导航中和索引选择中。最坏的情况是一个商品在这个页面显示之外,至少还会在这个页面以外的4个页面中显示。
      我们将要去掉这些相同的内容,并允许它们被蜘蛛爬但不被索引,固定目录的索引选择和层级导航。
      3.1. 无内容页面需设置成Noindex, follow
      安装 Yoast robots meta module 可确保设置成防止索引所有的无内容页面,如下:

      现在搜索引擎将通过所有的链接来到这些页面上但不会再索引中显示这些页面。

      magento网站seo优化之基本优化   

      ]]>
      Fri, 07 Aug 2015 10:03:13 +0000
      <![CDATA[magento网站seo优化之基本优化]]> https://www.360magento.com/blog/optimize-your-magento-website01/ 1. 基本的技术优化

      1.1. 普通优化设置

      Magento 是搜索引擎最友好的商用平台之一,但有几点需要关注以便优化你的 Magento SEO. 第一步是在使用最新的版本中激活 Server URL rewrites. 你可以在系统按钮下找到这个选项: System => Configuration => Web => Search Engines Optimization. 激活后,在这个页面上,另一个不错的选择是设置“Url Options ”下的 “Add store Code to Urls” ,在大多数情况下,把这个开关设为“No”更好。

      1.1.1. WWW 和 non-WWW

      在 “Unsecure” 和 “Secure” 的下拉菜单里你可以找到 Base URL, 在那里你可以设置你更喜欢的域名。你可以选择WWW的URL或者没有WWW的URL。改变这些设置你不会从www到non-www或者从 non-www到www建立一个重定向。所以你必须通过 .htaccess 文件建立 一个301重定向。除此之外,解决了 WWW vs non-WWW 的问题,这个重定向可以有效防止你的Magento URLs被加入SID问题,像?SID=b9c95150f7f70d6e77ad070259afa15d. 确保 Base URL 和重定向是一样的。编辑 .htaccess 文件时,你可以在根目录下的 .htaccess 文件中加入下面的重定向代码。

      大约 119 行:

      RewriteBase / RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/

      RewriteRule ^index\.php$ http://www.mydomain.com/ [R=301,L]

      也许,你的Magento不是安装在根目录而是在某个子目录下http://www.mydomain.com/magento/:

      RewriteBase /magento/ RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /magento/index\.php\ HTTP/

      RewriteRule ^index\.php$ http://www.mydomain.com/magento/ [R=301,L]

      1.2. 页眉优化设置

      安装Magento时默认的标题是 “Magento Commerce”。为了你的Magento商店得到它应得得流量,以下你必须了然于胸:

      搜索引擎着重于开头的词,所以如果你的关键字靠近页面标题的开头那你有更大的可能性让排名更好。

      人们扫视结果页面,一般看开头的几个词。如果你的关键字位于页面的的开始,那你被点击的可能性就大很多。

      首先你应该去掉默认的标题 “Magento Commerce”. 后台点击 System => Configuration => Design => HTML Head. 为你的网站选一个描述性好的标题,这个标题也会在几个没有内容的页面中使用,比如 “Contact Us” 和 “Popular Search Terms”.

      把页面标题加到你的店名中,包括目录和商品,把你的店名放在“标题后缀”中。保持前缀空白是个不错的选择,原因上面提到过。同时保持 “Default Description” 和 “Default Keywords” 空白。对于非产品展示页面,为防止整站索引,设置 “Default Robots” 为 “NOINDEX, NOFOLLOW” 会有所帮助,但对于别的页面来说要确保设置为 “INDEX, FOLLOW”.

      接下来优化你的网店页面的 ,最好的方法是加上 new canonical tag (新的规范标签)。你可以安装 Canonical URL’s for Magento Module 这个扩展以便把它们加到你的head种来改进你的Magento SEO。

      因某些原因Magento把未设置的meta机器人转为一个meta标签,方式如下:

      1. <meta name=”robots” content=”*” />

      这种方式会造成搜索引擎一些奇怪的行为,所以我们要把它移除。要从代码中移除这些空白的meta你可以安装 Yoast MetaRobots Module.

      1.3. CMS 页面优化设置

      第一眼看上去Magento似乎缺少华丽的CMS功能,但对于大多数使用者来说这已经足够了。简单 的CMS的好处之一是你能够控制页面的每一个方面。一旦你赋予每一个CMS页面一些不错的内容,选一个友好的URL和页面标题,(同时记住1.2小节中的 要点),到Meta数据标签处为每个你想要给它排名的 CMS页面写上描述。

      你可以保持”Keywords”栏空白。描述有一个很重要的作用:引诱人们去点击,所以确 保它描述的确实是他们所要点击页面的内容,那样可以引起他们的注意。因此,唯一的好的描述就是自己手写的,如果你考虑用自动描述软件来写描述,那还不如什 么也不做,让搜索引擎自动完成。

      如果你不使用meta描述,搜索引擎会在你的文件里找到关键字,并自动选择一条,那样在结果页面里会有一到两个醒目的词。

      1.4. 商品目录优化

      Magento 可以自定义目录名,让你的目录指向产品的URL。因为Magento对建立相同的内容这个功能的支持不够,很好的方式就是禁用它。设置它,点击 System => Configuration => Catalog => Search Engine Optimization and set “Use categories path for product URL’s to “no”.

      接着设置每一个目录的细节。点击Catalog => Manage Categories. 最重要的区域是:

      Meta 描述: 在这里放上吸引人的描述;记住人们会在搜索引擎的结果列表页中看到这个描述。

      页面标题: 保持页面标题空白,使用目录名包括父目录。但你按照要求制作目录时,标题会象你所输入的一样,没有父目录。

      URL 要点: 尝试保持短的但是关键字丰富的URL。移除像“the”,“and”,”for”等等没用的词。要注意的是你只能在“all store views”下设置, 对于多语种的商店你应该保持语言的独立。

      对于每一个商店界面,你可以指定名字,描述,页面标题和Meta数据。对多语种商店来说这真的是一个很棒的功能。

      1.5. 商品优化

      商品页面的优化和目录优化有些相似。你可以设置Meta信息为 “Default Values” 并使用于每一个 “Store View”. 注意对于 “Meta Title”, 这个将写在完全的页面标题上,包括目录但不包括标题的前缀/后缀,而不仅仅是商品的名称。

      Magento SEO中一个经常忽略的方面是你怎么处理你的图片。通过给图片写标签和考虑给你的图片起怎样的名字,你会从不同的图片搜索引擎得到不错的额外流量。

      ]]>
      Fri, 07 Aug 2015 09:51:24 +0000
      <![CDATA[magento在命令行刷新索引]]> https://www.360magento.com/blog/reindex-magento-command-line/ 有时,你可能会发现,需要通过命令行来重新索引Magento。这可能原因一大堆,例如,如果该索引超时或是通过Web界面没有完成。 Magento包含索引脚本,你可以找到

      Shell

      文件夹
      在这个文件夹,你可以执行一些命令

      检查所有索引的状态

      php indexer.php --status

      应该会输出类似下面:

      Product Attributes:            Pending
      Product Prices:                Pending
      Stock Status:                  Pending
      Tag Aggregation Data:          Pending
      Default Values:                Pending
      Catalog URL Rewrites:          Pending
      Product Flat Data:             Require Reindex
      Category Flat Data:            Pending
      Category Products:             Pending
      Catalog Search Index:          Pending
      

      重新索引单个索引

      每个索引都有自己的索引键,当magento需要重新索引时就需要引用它,要获得这些键,你可以使用一下命令

      php indexer.php --info
      

      你将会得到:

      catalog_product_attribute     Product Attributes
      catalog_product_price         Product Prices
      cataloginventory_stock        Stock Status
      tag_summary                   Tag Aggregation Data
      mana_db_replicator            Default Values
      catalog_url                   Catalog URL Rewrites
      catalog_product_flat          Product Flat Data
      catalog_category_flat         Category Flat Data
      catalog_category_product      Category Products
      catalogsearch_fulltext        Catalog Search Index
      

      重新索引单个索引,运行一下命令:

      php indexer.php --reindex [Index Option Code]
      

      可以用逗号来分离多个索引

      php indexer.php --reindex catalog_product_price,catalog_url,catalog_product_flat
      

      重新刷新所有索引

      下面的代码将通过每个索引循环,来重新建立索引

      php indexer.php --reindexall
      
      ]]>
      Tue, 04 Aug 2015 11:10:20 +0000
      <![CDATA[magento在首页显示最新产品]]> https://www.360magento.com/blog/magento-template002/ 打开Magento后台管理面板

      Go to CMS > Pages > Home page

      切换到 content 栏

      插入下面代码:

      {{block  type="catalog/product_new" column_count="6"  products_count="12" name="home.catalog.product.new"alias="product_homepage"template="catalog/product/list.phtml"}}

      释义:

      column_count="6" – 显示产品列的数量

      products_count="12" – 显示产品的数量

      ]]>
      Wed, 27 May 2015 13:57:58 +0000
      <![CDATA[magento中调用静态块的几种方法 ]]> https://www.360magento.com/blog/magento-template001/ 在后台创建一个order_form静态块
      Block Title :Order Form
      Identifier :order_form
      Status :Enabled
      Content :自定义内容

      1.如果要在.phtml文件中直接调用这个静态块,那可以采用以下方法

          <?php  
          $block = Mage::getModel('cms/block')  
           ->setStoreId(Mage::app()->getStore()->getId())  
           ->load('order_form');  
          $content = $block->getContent(); // Block的原始内容已经获得  
            
          $processor = Mage::getModel('core/email_template_filter');  
          echo $html = $processor->filter($content);  
          ?>  
      

      Mage::getModel('core/email_template_filter')->filter()是必须的,因为Static Block里可能包含Magento的模板语言(如:https://www.360magento.com/),fiter将翻译成实际的值 Magento中调用静态Block主要有两个地方。 是否感觉这代码太长了呢,那你还可以这么写

      <?php echo $this->getLayout()->createBlock(‘cms/block’)->setBlockId('order_form')->toHtml() ?>
      

      2.如何在CMS页面的Content中调用这个静态块呢?你可以采用以下方法

      {{block type="cms/block"  name="cms_test_block"  block_id="order_form" }}   
      

      将里面order_form改成你的静态块对应的block_id则可

      3.怎么样在layout中调用静态块呢?

        
      <reference name="footer">  
          <block type="cms/block" name="order_form" before="-">  
              <action method="setBlockId"><block_id>order_form</block_id></action>  
          </block>      
      </reference>   
         

      到此,你应该能够灵活的运用magento中的静态块了吧!

      ]]>
      Wed, 27 May 2015 13:33:10 +0000
      <![CDATA[Magento产品价格设置]]> https://www.360magento.com/blog/magento_product_price/ Magento为你的产品价格提供了很多选项。你可以设置特价,定时促销等等。要编辑你的产品价格,首先登录你的Magento后台,然后进入Catalog->Manage Products

      magento catalog Ma

      现在定位你要修改价格的产品上,点击它边上的Edit链接。

      magento price tab

      这里你将看到许多用来修改产品的选项。在左侧菜单选择Prices标签。

      magento product price

      在这里你可以修改产品的价格,下面是一些比较重要选项的说明:

      • Price(价格):你要出售产品的价格,必填项,最重要的信息
      • Cost(成本):你购买产品的价格
      • Tier Price(阶梯价格):可根据购买数量设定折扣
      • Special Price(特价):可设置特价及特价的起止事件,此选项不受购买数量的限制

      360magento提供专业的基于magento系统的电商网站开发服务,如有需求或相关咨询,请与我们联系

      ]]>
      Wed, 03 Sep 2014 13:00:00 +0000